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.
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.
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
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
setLpTokenIdentifierendpoint - 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/jsonrequired
| 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
- Payload
{- "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
- "funcName": "addInitialLiquidity",
- "value": "KFI=10000000,KLV=10000000"
}Response samples
- 200
{- "data": {
- "returnData": [
- "string"
], - "returnCode": "string",
- "returnMessage": "string"
}, - "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/jsonrequired
| scAddress required | string Pair contract address |
| funcName required | string Value: "addLiquidity" |
| args required | Array of strings Arguments:
|
| value required | string Token payments |
Responses
Request samples
- Payload
{- "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
- "funcName": "addLiquidity",
- "args": [
- "BigUint:1000000",
- "BigUint:10000000"
], - "value": "KFI=50000000,KLV=50000000"
}Response samples
- 200
{- "data": {
- "returnData": [
- "string"
], - "returnCode": "string",
- "returnMessage": "string"
}, - "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 receivesecond_token_amount_min: Minimum acceptable amount of second token to receive
Request Body schema: application/jsonrequired
| scAddress required | string |
| funcName required | string Value: "removeLiquidity" |
| args required | Array of strings Arguments:
|
| value required | string LP tokens to burn |
Responses
Request samples
- Payload
{- "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
- "funcName": "removeLiquidity",
- "args": [
- "BigUint:10000000",
- "BigUint:10000000"
], - "value": "KFIKLVLP-3O1A=10000000"
}Response samples
- 200
{- "data": {
- "returnData": [
- "string"
], - "returnCode": "string",
- "returnMessage": "string"
}, - "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
resumeendpoint 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/jsonrequired
| scAddress required | string |
| funcName required | string Value: "swapTokensFixedInput" |
| args required | Array of strings Arguments:
|
| value required | string Input token payment |
Responses
Request samples
- Payload
{- "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
- "funcName": "swapTokensFixedInput",
- "args": [
- "string:KLV",
- "BigUint:10000000"
], - "value": "KFI=20000000"
}Response samples
- 200
{- "data": {
- "returnData": [
- "string"
], - "returnCode": "string",
- "returnMessage": "string"
}, - "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
resumeendpoint 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/jsonrequired
| scAddress required | string |
| funcName required | string Value: "swapTokensFixedOutput" |
| args required | Array of strings Arguments:
|
| value required | string Input token payment (may be partially returned) |
Responses
Request samples
- Payload
{- "scAddress": "klv1qqqqqqqqqqqqqpgq9696g7x76kwrrh02fahn4rpem4v595t8c0nqgxzpmu",
- "funcName": "swapTokensFixedOutput",
- "args": [
- "string:KFI",
- "BigUint:10000000"
], - "value": "KLV=20000000"
}Response samples
- 200
{- "data": {
- "returnData": [
- "string"
], - "returnCode": "string",
- "returnMessage": "string"
}, - "error": "string",
- "code": "string"
}