fix: vault как ATA + фандинг беттора; E2E на localnet ok

This commit is contained in:
Caffeine
2026-09-10 02:12:07 +03:00
parent fb9a7f4e8b
commit f937c8993d
15 changed files with 267 additions and 148 deletions
+47
View File
@@ -0,0 +1,47 @@
# 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-адрес.