47 lines
2.7 KiB
Markdown
47 lines
2.7 KiB
Markdown
# TASK — Багфикс: vault_token в релейере должен быть ATA, а не PDA
|
||
|
||
Репозиторий: `smart-updown-token`, файл `relayer/src/ops.ts`.
|
||
|
||
## Проблема (обнаружена на localnet E2E)
|
||
Контракт переведён на SPL-токен (Фаза 1). В инструкциях `create_bet`/`close_bet`
|
||
аккаунт `vault_token` — это **ATA-аккаунт токена, который принадлежит владельцу
|
||
vaultPda** (PDA `[b"global", b"vault"]`). Правильный адрес:
|
||
`getAssociatedTokenAddress(mint, vaultPda(programId))` (allowOwnerOffCurve по PDA-владельцу).
|
||
|
||
Однако в релейере `createBet`/`closeBet` используется:
|
||
```ts
|
||
vaultToken: vaultPda(program.programId),
|
||
```
|
||
Это передаёт адрес **самого PDA-владельца** (не токен-аккаунт) — контракт
|
||
отвергнет транзакцию (wrong account), а `ensureVaultFunded` зовёт
|
||
`getTokenAccountBalance(vaultToken)` где vaultToken = vaultPda → «could not find account».
|
||
Т.е. ваулт ATA даже не создаётся в нужном месте.
|
||
|
||
## Что исправить (только `relayer/src/ops.ts`)
|
||
|
||
1. **`ensureVaultFunded`**:
|
||
- Получать ATA ваулта: `const vaultAta = await getAssociatedTokenAddress(mint, vaultPda, true);`
|
||
(третий аргумент `true` — allowOwnerOffCurve, иначе TokenOwnerOffCurveError).
|
||
- Создавать/получать: `getOrCreateAssociatedTokenAccount(connection, admin, mint, vaultPda, true)`.
|
||
- `getTokenAccountBalance` звать по **ATA-адресу** (`vaultAta`), не по vaultPda.
|
||
|
||
2. **`createBet`**:
|
||
- `vaultToken: await getAssociatedTokenAddress(mint, vaultPda(program.programId), true)`
|
||
|
||
3. **`closeBet`**:
|
||
- `vaultToken: await getAssociatedTokenAddress(mint, vaultPda(program.programId), true)`
|
||
|
||
## Гейты
|
||
- `npm run typecheck` — 0 ошибок.
|
||
- `npm run test` (check.ts) — зелёные проверки.
|
||
- (Если можно) быстрый локальный smoke: создать ваулт ATA, налить токен, create/close.
|
||
|
||
## НЕ делать
|
||
- Не трогать `program/` (контракт), не менять IDL.
|
||
- Не трогать логику цен/ставок.
|
||
- Не коммитить.
|
||
|
||
## Суть одным абзацем
|
||
`vault_token` в контракте — токен-счёт (ATA), всегда считаемый через
|
||
`getAssociatedTokenAddress(mint, vaultPda, true)`. Заменить все прямые
|
||
использования `vaultPda(...)` как адреса acкаунта на ATA-адрес. |