> For the complete documentation index, see [llms.txt](https://docs.flap.sh/flap/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flap.sh/flap/developers/flap-token-locker.md).

# Flap Token Locker

## Overview

`FlapTokenLocker` locks tokens under a vesting schedule while the locked position keeps earning. For a Flap tax token, the locker holds the tokens as one shareholder of the token's `Dividend` contract and splits every payout across its locks by locked principal, so a vesting allocation does not lose its dividends. Any other ERC20 locks as principal only.

Each lock has one beneficiary who can claim released principal, collect dividends, transfer the lock, or renounce it. The contract is a non-upgradeable singleton; admission rules live in a separate upgradeable `FlapTokenRegistry`.

## Deployed Addresses

| Chain       | Contract          | Address                                      |
| ----------- | ----------------- | -------------------------------------------- |
| BNB Mainnet | FlapTokenLocker   | `0x0000A8B6741441BB4Ba0DFE313a2bc7b2Cf10000` |
| BNB Mainnet | FlapTokenRegistry | `0x0000e9f9F5e469f0EEC27F192B4DdDE04D4c0000` |
| BNB Testnet | FlapTokenLocker   | `0x0000A8B6741441BB4Ba0DFE313a2bc7b2Cf10000` |
| BNB Testnet | FlapTokenRegistry | `0x0000e9f9F5e469f0EEC27F192B4DdDE04D4c0000` |

Both contracts are deployed with CREATE2, so the addresses are the same on every chain.

The ABI of the locker:

{% file src="/files/6Jvksy3uRZpSszn9emHq" %}

## How It Works

### Vesting

A lock releases on a curve fixed at creation: a first slice at `tgeDate` (the TGE), then one more slice every `cycle` seconds until everything is released. Nothing is released before `tgeDate`.

```
unlocked = locked * min(10000, tgeBps + elapsedCycles * cycleBps) / 10000
```

| Schedule                                              | Result                                                                    |
| ----------------------------------------------------- | ------------------------------------------------------------------------- |
| `tgeBps = 10000`                                      | Full lock: 100% releases at `tgeDate`; `cycle` and `cycleBps` are ignored |
| `tgeBps = 2000`, `cycle = 30 days`, `cycleBps = 1000` | 20% at TGE, then 10% every 30 days; fully released 240 days after TGE     |
| `tgeBps = 0`, `cycle = 1 days`, `cycleBps = 100`      | Nothing at TGE, then 1% per day for 100 days                              |

A partial release (`tgeBps < 10000`) requires a positive `cycle` and `cycleBps`. Releases are computed on demand from the timestamp; there is no keeper, and the beneficiary may claim any released amount at any time, in one or many calls.

### Dividends

All locks of the same token share one pool. The pool pulls the token's dividends from its `Dividend` contract and credits them to locks in proportion to their still-locked principal (MasterChef-style accumulator). Claiming principal shrinks a lock's future share; renouncing burns the remaining principal to `0xdead`.

### Fees

Fees are snapshotted into each lock at creation and never change afterwards.

| Fee          | Current | Cap |
| ------------ | ------- | --- |
| Creation fee | 0       |     |
| Principal    | 0%      | 10% |
| Dividend     | 5%      | 10% |

A negotiated fee can be issued off-chain as an EIP-712 `CustomFee` signed by `feeSigner`; see the [Integration Guide](/flap/developers/flap-token-locker/integration-guide.md#custom-fee).

## Supported Tokens

| Token                                                                                  | Behaviour                                                   |
| -------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Flap tax token, version 5 (TaxTokenV2), 6 (TaxTokenV3), 7 (non-tax TokenV3)            | Principal vests; dividends are collected through the locker |
| Flap token whose `dividendContract()` is zero (early launches with `dividendBps == 0`) | Principal only; `collect` and `pendingDividend` return 0    |
| Token the Portal does not know (any plain ERC20)                                       | Principal only; `collect` and `pendingDividend` return 0    |
| Flap token whose version is not open in the registry                                   | Rejected with `TokenNotAllowed`                             |

A pool's dividend token must be the token's own quote token (a native quote resolves to WBNB), the token itself, or a token the registry owner has allowlisted. Dividend tokens with transfer hooks that redirect or transform payouts (basket or vault wrapper tokens) are never admitted.

{% hint style="warning" %}
Rebasing tokens are not supported. Tokens in vault mode (`dividendBps == 0` with rewards paid by the vault directly to holders) lock fine, but the vault's rewards for the locked period accrue to the locker address and cannot be claimed; only dividends paid through the token's `Dividend` contract reach the beneficiary.
{% endhint %}

## Trust Assumptions

The locker owner cannot touch locked principal or change an existing lock's fee or schedule; it only sets fee parameters for new locks. Admission, which token versions and dividend tokens may open pools, is controlled by the registry owner, and the registry's ProxyAdmin can replace the registry implementation. Dividends depend on Flap's `Dividend` contract and its owner (the Portal), which can exclude an address, redirect a holder's payouts or swap the dividend token before its first deposit. None of these powers reach locked principal.

There is deliberately no sweep or rescue function. Tokens sent to the locker by mistake stay there.
