> For the complete documentation index, see [llms.txt](https://docs.kubchain.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kubchain.com/quickstart/launching-a-token-on-kub/kap-token-interfaces/kap-22.md).

# KAP-22

The following standard outlines a smart contract interface and logic for loyalty points tokens on KUB that behaves similarly to traditional loyalty points, enabling interoperability and composability within the decentralized ecosystem. By adhering to this standard, loyalty programs can leverage the benefits of blockchain technology, such as transparency, immutability, and programmability, while maintaining the familiar functionality of traditional loyalty points. It is proposed to derive the KAP-20 standard for KUB, with additional functions for periods and token expiration.

## Token Interface

### IAdminProjectRouter

#### isSuperAdmin

Check whether `_addr` is the Super Admin role in `_project`.

```solidity
function isSuperAdmin(address _addr, string calldata _project) external view returns (bool)
```

#### isAdmin

Check whether `_addr` is the Admin role in `_project`.

```solidity
function isAdmin(address _addr, string calldata _project) external view returns (bool)
```

### IKYCBitkubChain

#### kycsLevel

Returns the KYC Level of `_addr`

```solidity
function kycsLevel(address _addr) external view returns (uint256)
```

### IKAP20

#### totalSupply

Returns the total token supply.

```solidity
function totalSupply() external view returns (uint256)
```

#### decimals

Returns the number of decimals the token uses - e.g. `8`, means to divide the token amount by `100000000` to get its user representation.

```solidity
function decimals() external view returns (uint8)
```

{% hint style="info" %}
NOTE: This method is optional in ERC-20. In KAP-20, this is a required method.
{% endhint %}

#### symbol

Returns the symbol of the token. E.g. "HIX".

```solidity
function symbol() external view returns (string memory)
```

{% hint style="info" %}
NOTE: This method is optional in ERC-20. In KAP-20, this is a required method.
{% endhint %}

#### name

Returns the name of the token - e.g.`"MyToken"`.

```solidity
function name() external view returns (string memory)
```

{% hint style="info" %}
NOTE: This method is optional in ERC-20. In KAP-20, this is a required method.
{% endhint %}

#### allowance

Returns the amount which `spender` is still allowed to withdraw from `owner`.

```solidity
function allowance(address owner, address spender) external view returns (uint256)
```

#### approve

Allows `spender` to withdraw from your account multiple times, up to the `amount` amount. If this function is called again it overwrites the current allowance with `amount`.

```solidity
function approve(address spender, uint256 amount) external returns (bool)
```

{% hint style="info" %}
NOTE: To prevent attack vectors, clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to 0 before setting it to another value for the same spender. THOUGH The contract itself shouldn't enforce it, to allow backwards compatibility with contracts deployed before
{% endhint %}

#### adminApprove

Allows `spender` to withdraw from `owner` account multiple times, up to the `amount` amount. If this function is called again it overwrites the current allowance with `amount`. This method works similar to the `approve` method.

```solidity
function adminApprove(address owner, address spender, uint256 amount) external returns (bool)
```

{% hint style="info" %}
NOTE: This function can only be called by the Admin and Super Admin. This function is designed to create transactions automatically on behalf of token holders if they have been a victim of a fraudulent transaction.
{% endhint %}

#### transferFrom

Transfers `amount` amount of tokens from address `sender` to address `recipient`, and MUST fire the Transfer event.

The `transferFrom` method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD `throw` unless the `sender` account has deliberately authorized the sender of the message via some mechanism.

```solidity
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool)
```

{% hint style="info" %}
NOTE: Transfers of 0 values MUST be treated as normal transfers and fire the `Transfer` event.
{% endhint %}

#### adminTransfer

Transfers `amount` amount of tokens from address `sender` to address `recipient`, and MUST fire the Transfer event.

```solidity
function adminTransfer(address sender, address recipient, uint256 amount) external returns (bool)
```

{% hint style="info" %}
NOTE: This function can only be called by the Committee address required in the constructor. This function is designed to create transactions automatically on behalf of token holders if they have been a victim of a fraudulent transaction. This method works similar to the `transferFrom` method.
{% endhint %}

### Events

#### Transfer

MUST trigger when tokens are transferred, including zero value transfers.

A token contract which creates new tokens SHOULD trigger a Transfer event with the `from` address set to `0x0` when tokens are created.

```solidity
event Transfer(address indexed from, address indexed to, uint256 value)
```

#### Approval

MUST trigger on any successful call to `approve(address spender, uint256 value)`.

```solidity
event Approval(address indexed owner, address indexed spender, uint256 value)
```

### IKAP22

#### mint

Mint `amount` amount of token to `receiver` address without period, and MUST fire the `Mint` event.

```solidity
function mint(address receiver, uint256 amount) external returns (bool);
```

#### mintCurrentPeriod

Mint `amount` amount of token to `receiver` address with the current period.

```solidity
function mintCurrentPeriod(address receiver, uint256 amount) external returns (bool);
```

#### mintCustomPeriod

Mint `amount` amount of token to `receiver` address with the customizable `period` period.

```solidity
function mintCustomPeriod(address receiver, uint256 amount, uint256 period) external returns (bool);
```

#### transfer

Transfers `amount` amount of tokens to address `recipient`, and MUST fire the `TransferPeriod` event. The function SHOULD `throw` if the message caller's account balance does not have enough tokens to spend.

```solidity
function transfer(address recipient, uint256 amount) external returns (bool)
```

{% hint style="info" %}
NOTE: Tokens that are about to expired will be transferred first
{% endhint %}

#### transferNoPeriod

Transfer `amount` amount of token without period to `recipient` address.

```solidity
function transferNoPeriod(address recipient, uint256 amount) external returns (bool);
```

#### transferStampPeriod

Transfer `amount` amount of token without period to `recipient` address and stamp the `period` period to the token, and MUST fire the `TransferPeriod` event. The function SHOULD `throw` if the message caller's account balance does not have enough tokens to spend.

```solidity
function transferStampPeriod(address recipient, uint256 amount, uint256 period) external returns (bool);
```

#### transferCustomPeriod

Transfer `amount` amount of token within the desired `period` period to `recipient` address, and MUST fire the `TransferPeriod` event. The function SHOULD `throw` if the message caller's account balance does not have enough tokens to spend.

```solidity
function transferCustomPeriod(address recipient, uint256 amount, uint256 period) external returns (bool);
```

#### balanceOf

Returns the balance of active tokens in every period of `account` address.

```solidity
function balanceOf(address account) external view returns (uint256)
```

#### balanceOfAll

Returns the balance of tokens in every period of `account` address.

```solidity
function balanceOfAll(address account) external view returns (uint256);
```

#### balanceOfPeriod

Returns the balance of tokens in the selected `period` period of `account` address.

```solidity
function balanceOfPeriod(address account, uint256 period) external view returns (uint256);
```

#### balanceOfExpired

Returns the balance of expired tokens of `account` address.

```solidity
function balanceOfExpired(address account) external view returns (uint256);
```

#### burn

Burns the `amount` amount of tokens, and MUST fire the `Burn` event.

```solidity
function burn(uint256 amount) external returns (bool);
```

{% hint style="info" %}
NOTE: Tokens that are about to expired will be burned first
{% endhint %}

#### burnCustomPeriod

Burns the `amount` amount of tokens in the selected `period` period.

```solidity
function burnCustomPeriod(uint256 amount, uint256 period) external returns (bool);
```

#### pegToken

Returns the address of the token that is pegged with the loyalty token.

```solidity
function pegToken() external view returns (address);
```

#### ratio

Returns the ratio of the loyalty token and the pegged token.

```solidity
function ratio() external view returns (uint256);
```

#### currentIndex

Returns the index of the current period.

```solidity
function currentIndex() external view returns (uint256);
```

#### currentPeriod

Returns the current period.

```solidity
function currentPeriod() external view returns (uint256);
```

#### totalUnStampSupply

Returns the total amount of tokens without period.

```solidity
function totalUnStampSupply() external view returns (uint256);
```

#### totalExpiredUserSupply

Returns the total amount of expired tokens.

```solidity
function totalExpiredUserSupply() external view returns (uint256);
```

#### totalExpiredOwnerReceiverSupply

Returns the total amount of expired tokens of both `Owner` and `Receiver`.

```solidity
function totalExpiredOwnerReceiverSupply() external view returns (uint256);
```

#### readPeriodTimestamp

Returns the number of seconds in the selected period.

```solidity
function readPeriodTimestamp(uint256 page, uint256 limit) external view returns (uint256[] memory);
```

#### setPeriodTimeStamp

Sets the amount of seconds in the selected period.

```solidity
function setPeriodTimeStamp(uint256[] calldata index, uint256[] calldata timestamp) external returns (bool);
```

### KAP-22 Events

#### Mint

MUST trigger on any successful call to `mint(address receiver, uint256 amount)`.

```solidity
event Mint(uint256 indexed period, address indexed receiver, uint256 amount);
```

#### Burn

MUST trigger on any successful call to `burn(uint256 amount)`.

```solidity
event Burn(address indexed owner, uint256 amount);
```

#### TransferPeriod

MUST trigger on any successful call to `transfer(address recipient, uint256 amount)`, `transferStampPeriod(address recipient, uint256 amount, uint256 period)`, and `transferCustomPeriod(address recipient, uint256 amount, uint256 period)`.

```solidity
event TransferPeriod(address indexed sender, address indexed recipient, uint256 value, uint256 period);
```

### IKToken

#### internalTransfer

Transfers `amount` amount of tokens to address `recipient` internally from `sender`, and MUST fire the `Transfer` event. The function SHOULD `throw` if the message caller's account balance does not have enough tokens to spend. Tokens can be transferred between internal addresses that have completed KYC for both the sender and the recipient using the internalTransfer function.

```solidity
function internalTransfer(address sender, address recipient, uint256 amount) external returns (bool)
```

{% hint style="info" %}
NOTE: This function can only be called by the Super Admin and the Transfer Router.
{% endhint %}

#### externalTransfer

Transfers `amount` amount of tokens to address `recipient` externally from `sender`, and MUST fire the `Transfer` event. The function SHOULD `throw` if the message caller's account balance does not have enough tokens to spend. The function externalTransfer allows tokens to be transferred between addresses that have only passed the sender's KYC verification process.

```solidity
function externalTransfer(address sender, address recipient, uint256 amount) external returns (bool)
```

{% hint style="info" %}
NOTE: This function can only be called by the Super Admin and the Transfer Router.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kubchain.com/quickstart/launching-a-token-on-kub/kap-token-interfaces/kap-22.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
