> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Правила кривых LaunchLab

> Как платформа ограничивает параметры запуска, которые могут выбирать создатели: группы проверок, модель ограничений (поле, операция, значение) и девять сценариев — точные уровни, диапазоны значений, потолки оценки при выпуске, минимумы миграции, гейтинг по типам токенов и ограниченные по времени акции.

<Info>
  **Эта страница переведена с помощью ИИ. За эталон принимается английская версия.**

  [Открыть английскую версию →](/products/launchlab/curve-rules)
</Info>

<Info>
  **Правило кривой** — это ответ платформы на вопрос «какие запуски я готов размещать?». [`GlobalConfig`](/ru/products/launchlab/global-config) устанавливает протокольный минимум — минимум 10M предложения, минимум 20% предложения продано на кривой и так далее — и эти минимумы намеренно широкие, чтобы под них подходила любая платформа. Правило кривой — это то, где вы сужаете их до формы, которую ваш продукт действительно поддерживает.

  Правила хранятся в собственном аккаунте `PlatformCurveRule`, по одному на пару (платформа, [`GlobalConfig`](/ru/products/launchlab/global-config)). Они могут только сужать то, что уже разрешает конфиг; правило никогда не может расширить протокольное ограничение.
</Info>

## Концептуальная модель

Три уровня, от внешнего к внутреннему:

```
GlobalConfig       протокольный минимум      "supply >= 10M, sell rate >= 20%, ..."
  └─ PlatformCurveRule   ваше правило     "и на моей платформе: одна из этих форм"
       └─ группа проверок    одна форма     "supply = 1B И сбор средств в [80, 90] SOL"
            └─ ограничение одна проверка    "(Supply, Eq, 1_000_000_000)"
```

Два уровня вложенности делают это выразительным:

* **Ограничения внутри одной группы объединяются через AND.** Все они должны выполняться.
* **Группы внутри одного правила объединяются через OR.** Запуск разрешён, как только он удовлетворяет любой одной группе.

Таким образом, группа — это одна допустимая *форма*, а правило — это меню форм, которые вы предлагаете. Правило может содержать до 10 групп, а группа — до 25 ограничений.

Два граничных случая стоит запомнить:

| Состояние                                            | Значение                                                                     |
| ---------------------------------------------------- | ---------------------------------------------------------------------------- |
| Нет аккаунта правила или правило с нулевыми группами | Платформа не ограничивает параметры запуска для этого конфига.               |
| Группа с нулевыми ограничениями                      | Эта группа соответствует каждому запуску, поэтому всё правило разрешает всё. |

Правило вступает в силу только при `PlatformConfig.restrict_curve_param` равном `1`. При `0` программа вообще не читает правила, это также переключатель, который вы используете для развёртывания правила и его отката.

## Ограничения

Ограничение — это тройка `(поле, операция, значение)`. Ничего больше — никаких выражений, никакой вложенности.

```rust theme={null}
pub struct ParamConstraint {
    pub field: u8,    // какой параметр запуска, см. таблицу ниже
    pub op:    u8,    // 0 Eq, 1 Gte (мин), 2 Lte (макс), 3 Neq
    pub value: u128,
}
```

**Диапазон — это два ограничения** на одно поле внутри одной группы: `Gte` для минимума и `Lte` для максимума. Одна пара `(поле, операция)` не может появиться дважды в одной группе, что предотвращает написание двух противоречивых минимумов.

### Поля

<Info>
  Идентификаторы полей постоянны. Новые поля добавляются только в конец, поэтому идентификатор никогда не меняет своё значение, как только аккаунт правила его содержит.
</Info>

| id | Поле                     | Единица         | Примечания                                                                                                              |
| -- | ------------------------ | --------------- | ----------------------------------------------------------------------------------------------------------------------- |
| 0  | `CurveType`              | enum            | 0 constant product, 1 fixed price, 2 linear price                                                                       |
| 1  | `MigrateType`            | enum            | Новые запуски в любом случае должны быть `1` (CPMM)                                                                     |
| 2  | `MigrateCpmmFeeOn`       | enum            | 0 только quote, 1 оба токена                                                                                            |
| 3  | `Supply`                 | базовые единицы | Полное предложение токена                                                                                               |
| 4  | `TotalSellA`             | базовые единицы | Продано на кривой. Только для constant-product конфигов — см. [Ограничения по типу кривой](#ограничения-по-типу-кривой) |
| 5  | `TotalFundRaisingB`      | единицы quote   | Целевой объём сбора средств                                                                                             |
| 6  | `TotalLockedAmount`      | базовые единицы | Бюджет vesting                                                                                                          |
| 7  | `CliffPeriod`            | секунды         | Ожидание перед началом разблокировки                                                                                    |
| 8  | `UnlockPeriod`           | секунды         | Длительность разблокировки                                                                                              |
| 9  | `BaseTokenProgram`       | enum            | 0 SPL Token, 1 Token-2022                                                                                               |
| 10 | `TransferFeeEnabled`     | bool            | 1 когда базовый mint имеет `TransferFeeConfig`                                                                          |
| 11 | `TransferFeeBasisPoints` | 1/10 000        | 0 без расширения                                                                                                        |
| 12 | `TransferFeeMaximumFee`  | базовые единицы | 0 без расширения                                                                                                        |
| 13 | `SellRateA`              | 1/1 000 000     | Производное: `TotalSellA / Supply`. Только constant-product                                                             |
| 14 | `LockRate`               | 1/1 000 000     | Производное: `TotalLockedAmount / Supply`                                                                               |
| 15 | `MigrateAmountA`         | базовые единицы | Производное: `Supply − TotalSellA − TotalLockedAmount`. Только constant-product                                         |
| 16 | `MigrateRateA`           | 1/1 000 000     | Производное: `MigrateAmountA / Supply`. Только constant-product                                                         |
| 17 | `FundRaisingRateB`       | 1/1 000 000     | Производное: `TotalFundRaisingB / Supply`                                                                               |
| 18 | `UnixTimestamp`          | секунды         | Время блока запуска                                                                                                     |

Производные поля — это то, что делает правила портативными. Привязка `Supply` и `TotalFundRaisingB` к точным числам фиксирует одну форму запуска; ограничение `FundRaisingRateB` фиксирует *отношение* между ними и позволяет создателю выбрать любое предложение, которое его сохраняет.

<Warning>
  Поля ставок сравнимы только внутри одного `GlobalConfig`, потому что их знаменатели зависят от quote mint этого конфига и его decimals. На практике это не ограничение: правило по конструкции ограничено одним конфигом.
</Warning>

## Девять сценариев

Каждый сценарий ниже — это одно правило. Ограничения записаны как `(поле, операция, значение)`.

### 1. Один стандартный уровень

Самое простое правило и точное поведение, которое предлагал снятый с производства whitelist параметров кривой: одна форма, зафиксированная.

| Группа | Ограничения                                                                                         |
| ------ | --------------------------------------------------------------------------------------------------- |
| 0      | `(Supply, Eq, 1_000_000_000e6)`, `(TotalSellA, Eq, 800_000_000e6)`, `(TotalFundRaisingB, Eq, 85e9)` |

Любой запуск, отклоняющийся в любом из трёх параметров, отклоняется с `CurveParamNotMatchPlatformRule`.

### 2. Диапазон вместо числа

Причина существования диапазонов: создатель выбирает целевой объём сбора средств, с которым вы согласны, без перечисления каждого значения.

| Группа | Ограничения                                                                                          |
| ------ | ---------------------------------------------------------------------------------------------------- |
| 0      | `(Supply, Eq, 1_000_000_000e6)`, `(TotalFundRaisingB, Gte, 50e9)`, `(TotalFundRaisingB, Lte, 200e9)` |

Одна группа, четыре ограничения, и создатель имеет коридор 50–200 SOL. При старом whitelist это требовало одной записи на каждое допустимое значение, и лимит в десять записей делал это невозможным.

### 3. Уровни рядом

Группы объединяются через OR, поэтому каждый уровень — это группа.

| Группа | Ограничения                                                         | Уровень     |
| ------ | ------------------------------------------------------------------- | ----------- |
| 0      | `(Supply, Eq, 1_000_000_000e6)`, `(TotalFundRaisingB, Eq, 85e9)`    | Стандартный |
| 1      | `(Supply, Eq, 100_000_000e6)`, `(TotalFundRaisingB, Eq, 30e9)`      | Малый       |
| 2      | `(Supply, Eq, 10_000_000_000e6)`, `(TotalFundRaisingB, Gte, 500e9)` | Кит         |

Порядок имеет значение для вычислений, а не для семантики: оценка останавливается на первой группе, которая совпадает, поэтому поместите ваш наиболее используемый уровень первым.

### 4. Диапазон оценки при выпуске

`FundRaisingRateB` — это `TotalFundRaisingB / Supply` в миллионных долях. Ограничение его ограничивает, насколько богато токен может выпуститься, независимо от предложения, которое выбрал создатель.

| Группа | Ограничения                                                           |
| ------ | --------------------------------------------------------------------- |
| 0      | `(FundRaisingRateB, Gte, 60_000)`, `(FundRaisingRateB, Lte, 120_000)` |

С предложением 1e12 и 9-десятичным quote mint, `85e9 / 1e12 × 1e6 = 85_000` находится внутри этого диапазона. Создатель, который удвоит предложение, должен примерно удвоить целевой объём, чтобы остаться в нём — это и есть смысл. Два ограничения заменяют то, что иначе было бы таблицей пар `(предложение, целевой объём)`.

### 5. Минимум миграции

`MigrateRateA` — это доля предложения, которая действительно попадает в пул CPMM при выпуске: `Supply − TotalSellA − TotalLockedAmount`, делённое на предложение. Это глубина выпущенного пула, и это единственный протокольный рычаг без эквивалента на стороне платформы до появления правил.

| Группа | Ограничения                    |
| ------ | ------------------------------ |
| 0      | `(MigrateRateA, Gte, 150_000)` |

Минимум 15% предложения достигает пула. Создатель не может продать 95% на кривой и оставить поверхностную книгу позади.

<Note>
  Если параметры не складываются — заблокированная сумма больше, чем остаётся после продажи на кривой — производное значение не может быть вычислено и ограничение не срабатывает, поэтому запуск отклоняется, а не молча разрешается.
</Note>

### 6. Vesting, который вы действительно обеспечиваете

`GlobalConfig.max_lock_rate` ограничивает vesting сверху. Правило может установить минимум, и требовать реальный cliff.

| Группа | Ограничения                                                                            |
| ------ | -------------------------------------------------------------------------------------- |
| 0      | `(LockRate, Gte, 50_000)`, `(LockRate, Lte, 200_000)`, `(CliffPeriod, Gte, 2_592_000)` |

От 5% до 20% предложения заблокировано, с минимум 30-дневным cliff. Полезно для платформы, чей слоган — «никаких запусков с мгновенной разблокировкой».

### 7. Гейтинг по типу токена

`BaseTokenProgram` и `TransferFeeEnabled` независимы, что важно: mint Token-2022 без `TransferFeeConfig` сообщает `TransferFeeEnabled = 0` так же, как mint SPL Token.

| Намерение                                 | Группа | Ограничения                                                |
| ----------------------------------------- | ------ | ---------------------------------------------------------- |
| Только SPL Token                          | 0      | `(BaseTokenProgram, Eq, 0)`                                |
| Только Token-2022                         | 0      | `(BaseTokenProgram, Eq, 1)`                                |
| Token-2022, без комиссии за передачу      | 0      | `(BaseTokenProgram, Eq, 1)`, `(TransferFeeEnabled, Eq, 0)` |
| Без комиссии за передачу, любая программа | 0      | `(TransferFeeEnabled, Eq, 0)`                              |

### 8. Условный потолок комиссии за передачу

Нет оператора «если», и он не нужен — две группы выражают условие.

| Группа | Ограничения                                                                                                | Читается как                                                                         |
| ------ | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| 0      | `(TransferFeeEnabled, Eq, 0)`                                                                              | Без комиссии: хорошо                                                                 |
| 1      | `(TransferFeeEnabled, Eq, 1)`, `(TransferFeeBasisPoints, Lte, 100)`, `(TransferFeeMaximumFee, Gte, 1_000)` | С комиссией: максимум 1%, и максимальная комиссия, которая действительно установлена |

Нулевая ставка `TransferFeeConfig` не проходит через группу 0: расширение присутствует, поэтому `TransferFeeEnabled` равен `1` и только группа 1 может его принять.

### 9. Ограниченная по времени акция, запланированная заранее

`UnixTimestamp` — это время блока запуска, поэтому группа может нести своё собственное окно действительности. Вы пишете обе группы сегодня, и переключение происходит само по себе.

| Группа | Ограничения                                                             | Окно                         |
| ------ | ----------------------------------------------------------------------- | ---------------------------- |
| 0      | `(UnixTimestamp, Lte, 1_767_225_600)`, `(TotalFundRaisingB, Gte, 30e9)` | Период акции: минимум 30 SOL |
| 1      | `(UnixTimestamp, Gte, 1_767_225_601)`, `(TotalFundRaisingB, Gte, 80e9)` | После: минимум 80 SOL        |

На границе не требуется никакой транзакции. Стоимость — две группы вместо одной.

## Ограничения по типу кривой

Четыре поля читают `TotalSellA`: `TotalSellA`, `SellRateA`, `MigrateAmountA` и `MigrateRateA`. На constant-product конфиге создатель предоставляет это число. На fixed-price или linear-price конфиге кривая вместо этого его выводит, и значение, которое программа сравнивает, — это `0`, что отклонило бы каждый запуск.

Чтобы не позволить вам написать правило, которое молча блокирует ваш собственный конфиг, программа отказывает в этих четырёх полях во время записи на non-constant-product конфиге с `CurveRuleFieldNotSupportedByCurve`. Сегодня существуют только constant-product конфиги, поэтому на практике вы не встретите эту ошибку.

## Проверьте перед отправкой

Обе стороны проверки on-chain доступны off-chain, поэтому ни создателю, ни платформе не нужно изучать правило, наблюдая за откатом транзакций.

<Info>
  **Баннер версии.**

  * SDK: `@raydium-io/raydium-sdk-v2@0.2.42-alpha` — это версия, к которой привязаны все остальные примеры кода на этом сайте. Два помощника ниже поступают с выпуском SDK, который поставляет поддержку curve-rule; до тех пор портируйте их из `platform_curve_rule.rs` программы или вызовите программу и прочитайте код ошибки.
  * Кластер: сначала протестируйте на Solana `devnet` — см. [Сначала протестируйте на devnet](#сначала-протестируйте-на-devnet).
  * Program ID: см. [`reference/program-addresses`](/ru/reference/program-addresses)

  Оба помощника — это чистые функции. Они не касаются RPC, поэтому безопасно запускать их на каждом нажатии клавиши в форме.
</Info>

### Перед запуском: пройдут ли эти параметры?

`checkLaunchAgainstCurveRule` точно отражает проверку программы во время запуска, включая её поведение fail-closed. Запустите её в форме запуска и вы можете отключить кнопку отправки с причиной вместо того, чтобы позволить создателю платить за откатившуюся транзакцию.

```ts theme={null}
import {
  checkLaunchAgainstCurveRule,
  getPdaPlatformCurveRule,
  LaunchpadCurveRuleBaseTokenProgram,
  LaunchpadCurveRuleField,
  PlatformCurveRule,
} from "@raydium-io/raydium-sdk-v2";
import BN from "bn.js";

const platformConfig = await raydium.launchpad.getPlatformConfig(platformConfigId);

// при 0 программа вообще не читает правила, поэтому нечего проверять
if (platformConfig.restrictCurveParam !== 0) {
  const ruleId = getPdaPlatformCurveRule(programId, platformConfigId, configId).publicKey;
  const ruleAccount = await connection.getAccountInfo(ruleId);

  const result = checkLaunchAgainstCurveRule({
    // undefined когда аккаунт не существует — платформа не написала правило для этого конфига
    rule: ruleAccount === null ? undefined : PlatformCurveRule.decode(ruleAccount.data),
    context: {
      curveType: globalConfig.curveType,
      migrateType: 1,
      migrateCpmmFeeOn: 0,
      supply: new BN("1000000000000000"),
      totalSellA: new BN("793100000000000"),
      totalFundRaisingB: new BN("85000000000"),
      totalLockedAmount: new BN(0),
      cliffPeriod: new BN(0),
      unlockPeriod: new BN(0),
      baseTokenProgram: LaunchpadCurveRuleBaseTokenProgram.SplToken,
      // опустите transferFee полностью когда базовый mint не имеет расширения transfer-fee
      unixTimestamp: new BN(Math.floor(Date.now() / 1000)),
    },
  });

  if (!result.ok) {
    // каждая группа отклонила запуск; каждая запись перечисляет все неудовлетворённые ограничения этой группы
    for (const group of result.groupFailures) {
      for (const c of group.unsatisfied) {
        console.log(
          `группа ${group.groupId}: ${LaunchpadCurveRuleField[c.field]} равен ${c.actual ?? "не вычислим"},`,
          `правило хочет op ${c.op} ${c.value.toString()}`,
        );
      }
    }
  }
}
```

Три вещи, которые помощник воспроизводит, а не приблизительно:

* **Отсутствующий аккаунт правила и правило без группы оба проходят.** Так же как и группа без ограничений. Передайте `rule: undefined` для несуществующего аккаунта; не рассматривайте это как отклонение.
* **Невычислимые значения не срабатывают.** Нулевое предложение не имеет ставок, и заблокированная сумма больше, чем остаётся после продажи на кривой, не имеет суммы миграции. `actual` возвращается `undefined` и ограничение считается неудовлетворённым, точно как on-chain.
* **Все неудовлетворённые ограничения сообщаются, не только первое.** Программа короткозамыкается, потому что ей нужен только вердикт; помощник собирает всё, чтобы ваша форма могла перечислить каждую проблему сразу.

Единственное, что он не может знать, — это время блока, в которое ваша транзакция действительно приземлится. Если правило использует `UnixTimestamp` рядом с границей, рассматривайте прохождение как предварительное.

### Перед написанием правила: действительна ли эта группа?

`checkCurveRuleGroupWritable` отражает валидацию во время записи `UpdatePlatformCurveRule` — идентификаторы ограничений, правило дублирования `(поле, операция)`, оба лимита подсчёта и ограничение по типу кривой. Запустите её в инструменте администратора платформы перед подписанием.

```ts theme={null}
import {
  checkCurveRuleGroupWritable,
  LaunchpadCurveRuleField,
  LaunchpadCurveRuleOp,
} from "@raydium-io/raydium-sdk-v2";

const constraints = [
  { field: LaunchpadCurveRuleField.Supply, op: LaunchpadCurveRuleOp.Eq, value: new BN("1000000000000000") },
  { field: LaunchpadCurveRuleField.TotalFundRaisingB, op: LaunchpadCurveRuleOp.Gte, value: new BN("50000000000") },
  { field: LaunchpadCurveRuleField.TotalFundRaisingB, op: LaunchpadCurveRuleOp.Lte, value: new BN("200000000000") },
];

const writable = checkCurveRuleGroupWritable({
  groupId: 0,
  constraints,
  curveType: globalConfig.curveType,
  // идентификаторы, которые правило уже содержит, поэтому замена группы не ошибочно принимается за добавление
  existingGroupIds: existingRule?.groups.map((g) => g.groupId) ?? [],
});

// каждая ошибка несёт код ошибки программы, с которым транзакция была бы отклонена
if (!writable.ok) console.log(writable.errors);
```

<Note>
  Прохождение этой проверки означает, что транзакция не будет отклонена за неправильный формат. Это ничего не говорит о том, является ли правило тем, что вы имели в виду — группа может быть совершенно действительной и всё ещё отклонять каждый запуск, который может произвести ваш UI. Для этого предназначена проверка на стороне запуска выше: после написания группы запустите каждую форму, которую может произвести ваш продукт, через `checkLaunchAgainstCurveRule` и подтвердите, что каждая всё ещё находит группу.
</Note>

### Сначала протестируйте на devnet

Включение `restrict_curve_param` на mainnet меняет то, что могут делать ваши создатели, немедленно, для каждого запуска. Отрепетируйте всю последовательность на devnet перед тем, как трогать mainnet:

1. Создайте конфиг платформы и правило на devnet, и напишите те же группы, которые вы намерены отправить.
2. Запустите каждую форму запуска, которую может произвести ваш UI, через `checkLaunchAgainstCurveRule`, и подтвердите, что вердикты — это те, которые вы ожидаете — как формы, которые должны пройти, так и формы, которые должны быть отклонены.
3. Включите `restrict_curve_param`, затем действительно запустите токен, который должен пройти, и один, который должен быть отклонен. Второй должен не пройти с `CurveParamNotMatchPlatformRule` (`6025`), а не с `NotEnoughRemainingAccounts` (`6018`) — последнее означает, что ваш builder не добавляет PDA правила и проверка не действительно выполняется.
4. Только затем повторите на mainnet, в том же порядке.

Пункт 3 — это тот, на котором стоит настаивать. Off-chain помощник и on-chain программа — это две реализации одних и тех же правил, и запуск на devnet — это то, что доказывает, что они согласны для вашего правила — включая то, что ваш builder запуска передаёт аккаунт вообще.

## Управление правилом

### Делегированный менеджер

Редактирование правил — это рутинная работа; ключ администратора платформы обычно — это multisig. `PlatformConfig.curve_rule_manager` существует именно для этого: установите его один раз через `UpdatePlatformConfig::CurveRuleManager`, и этот горячий кошелёк может затем создавать, обновлять, удалять и закрывать аккаунты правил самостоятельно. Администратор платформы сохраняет ту же власть параллельно, поэтому потерянный ключ менеджера восстанавливаем — ротируйте его другим вызовом администратора.

Область скомпрометированного ключа менеджера: он может ослабить или удалить ваши правила параметров и вернуть себе rent аккаунта правила. Он не может трогать кошельки комиссий, vesting, конфиг CPMM, не может переключить `restrict_curve_param` и не может нарушить лимит `GlobalConfig`. Рассматривайте это как ключ конфигурации, а не ключ казны.

### Rent следует за содержимым

Аккаунт правила создаётся без группы и изменяется в размере при каждом изменении, поэтому вы платите за правила, которые вы действительно написали. Удаление группы возвращает разницу подписывающему.

| Содержимое правила              | Размер аккаунта | Rent         |
| ------------------------------- | --------------- | ------------ |
| Пусто (только что создано)      | 150 байт        | \~0.0019 SOL |
| 1 группа, 2 ограничения         | 200 байт        | \~0.0023 SOL |
| 3 группы, 4 ограничения каждая  | 408 байт        | \~0.0037 SOL |
| 10 групп, 25 ограничений каждая | 4 790 байт      | \~0.034 SOL  |

### Порядок развёртывания

1. Отрепетируйте всю последовательность на devnet — см. [Сначала протестируйте на devnet](#сначала-протестируйте-на-devnet).
2. Создайте аккаунт правила и напишите его группы. Ничего не меняется — при `restrict_curve_param` всё ещё `0` программа их не читает.
3. Проверьте правило off-chain с [`checkLaunchAgainstCurveRule`](#перед-запуском-пройдут-ли-эти-параметры): для каждой формы запуска, которую может произвести ваш UI, подтвердите, что какая-то группа её принимает.
4. Установите `restrict_curve_param` на `1`. С этого момента запуски ваших создателей проверяются.
5. Чтобы откатить, установите его на `0` снова. Аккаунт правила остаётся нетронутым.

<Warning>
  Ваш builder запуска должен добавить PDA правила в `remaining_accounts` пока `restrict_curve_param` равен `1`. Программа требует, чтобы аккаунт был присутствующим даже когда он ещё не существует, поэтому создатель не может пропустить проверку, опустив его — отсутствующий аккаунт — это `NotEnoughRemainingAccounts`, а не прохождение. Вывод — это `[b"platform_curve_rule", platform_config, global_config]`.
</Warning>

## Стоимость во время запуска

Проверка выполняется при каждом запуске пока она включена, поэтому её стоимость вычислений — это налог за запуск. Измеренный end-to-end — вывод PDA, сканирование `remaining_accounts`, десериализация и оценка:

| Содержимое правила              | Дешёвые поля | Производные поля |
| ------------------------------- | ------------ | ---------------- |
| Включено, нет аккаунта правила  | 1 936        | —                |
| 1 группа, 2 ограничения         | 2 576        | 2 926            |
| 3 группы, 4 ограничения каждая  | 3 624        | 5 724            |
| 10 групп, 25 ограничений каждая | 24 344       | 68 094           |

«Дешёвый» — это прямое чтение поля, такое как `Supply`; «производный» — это вычисленный, такой как `MigrateRateA`, который стоит примерно 223 CU за ограничение против примерно 48. Даже полностью загруженное правило производных ограничений остаётся внутри трети бюджета по умолчанию 200 000 CU за инструкцию, и реалистичное трёхгруппное правило — под 6 000. Группы оцениваются до тех пор, пока одна не совпадёт, поэтому размещение вашего общего уровня первым — это бесплатная экономия.

## Куда дальше

* [`products/launchlab/platform-config`](/ru/products/launchlab/platform-config) — поля `PlatformConfig`, которые управляют и делегируют правила.
* [`products/launchlab/global-config`](/ru/products/launchlab/global-config) — протокольные минимумы, которые правило сужает.
* [`products/launchlab/instructions`](/ru/products/launchlab/instructions) — четыре инструкции правила и их аккаунты.
* [`products/launchlab/accounts`](/ru/products/launchlab/accounts) — `PlatformCurveRule` в инвентаре аккаунтов.
* [`sdk-api/typescript-sdk`](/ru/sdk-api/typescript-sdk) — поверхность SDK, в которой живут два помощника проверки.
* [`reference/changelog/2026-08-31-launchlab-platform-curve-rules`](/ru/reference/changelog/2026-08-31-launchlab-platform-curve-rules) — что заменило whitelist параметров кривой и что должны изменить декодеры.

Источники:

* `raydium-launch/programs/launchpad/src/states/platform_curve_rule.rs` — `PlatformCurveRule`, `CurveRuleGroup`, `ParamConstraint`, пространства идентификаторов полей и операций, и `CurveRuleContext::value_of`.
* `raydium-launch/programs/launchpad/src/utils/platform_curve_rule.rs` — проверка во время запуска.
* `raydium-launch/programs/launchpad/src/instructions/platform/` — `create`, `update`, `remove` и `close_platform_curve_rule`.
