fix: vault как ATA + фандинг беттора; E2E на localnet ok
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# TASK — Фикс: сделать vault_token обычным ATA-токен-счётом (убрать seeds = PDA)
|
||||
|
||||
Репозиторий: `smart-updown-token`. Файлы: `program/programs/smart-updown/src/instructions/create_bet.rs`
|
||||
и `.../close_bet.rs`.
|
||||
|
||||
## Проблема (обнаружено на localnet E2E)
|
||||
Токен-аккаунт ваулта объявлен так:
|
||||
```rust
|
||||
#[account(
|
||||
mut,
|
||||
seeds = [GLOBAL_SEED, VAULT_SEED], // ← требует адрес == PDA([global,vault])
|
||||
)]
|
||||
pub vault_token: Account<'info, TokenAccount>
|
||||
```
|
||||
Anchor проверяет, что **адрес `vault_token` == PDA([global,vault])**. Но казённый
|
||||
(escrow) токен-счёт у нас — это ATA от владельца `vaultPda`: адрес
|
||||
`getAssociatedTokenAddress(mint, vaultPda)`, который НЕ равен PDA. Отсюда
|
||||
`Error Code: ConstraintSeeds` — перевод в ваулт невозможен.
|
||||
|
||||
У `bettor_token` такой проблемы нет (там обычный `Account<TokenAccount>`, адрес = ATA игрока).
|
||||
|
||||
## Что исправить
|
||||
|
||||
### 1. `create_bet.rs`
|
||||
У `vault_token` **убрать блок `seeds = [GLOBAL_SEED, VAULT_SEED]`** — оставить просто:
|
||||
```rust
|
||||
#[account(mut)]
|
||||
pub vault_token: Account<'info, TokenAccount>,
|
||||
```
|
||||
(оставить поле `bump` больше не нужно — удалить его из struct, если он был).
|
||||
Это сделает адрес любого токен-счёта (ATA ваулта) приемлемым.
|
||||
|
||||
### 2. `close_bet.rs`
|
||||
То же самое: у `vault_token` убрать `seeds = [...]`. НО: раз адрес больше не фиксируется
|
||||
seeds, передавать/подписывать перевод нужно от **владельца-пользователя (vaultPda)**.
|
||||
В `close_bet` AUTHORITY перевода остаётся владелец аккаунта (поле `owner` токен-счёта).
|
||||
Проверить: signer_seeds `[GLOBAL_SEED, VAULT_SEED, bump]` должны по-прежнему давать
|
||||
vaultPda (это и есть владелец ATA). Так как сигнатура от PDA не меняется, seed-фразы
|
||||
в `close_bet.rs` (для подписи CPI) СТАВЯТСЯ из `ctx.accounts.vault_token` owner.
|
||||
Возможно понадобится отдельный аккаунт `vault_authority: PDA([global,vault])`, чтобы
|
||||
передать в signer seeds — оценить и сделать аккуратно (стандартный Anchor escrow).
|
||||
|
||||
### 3. Пересборка и проверка
|
||||
- `anchor build` зелёный.
|
||||
- IDL перегенерировать (`anchor idl build`), синхронизировать `relayer/idl/smart_updown.json`.
|
||||
- `npm run typecheck` / `npm test` в `relayer/` — зелёные (если тесты проверяют seeds — обновить).
|
||||
|
||||
## Важно (архитектурно)
|
||||
`vault_token` — это ATA от владельца `vaultPda` (адрес `getAssociatedTokenAddress(mint, vaultPda)`).
|
||||
Контракт НЕ должен требовать конкретного адреса — только владельца-подпись для withdraw.
|
||||
Всё, что нужно — чтобы в `close_bet` authority (тот, кто подписывает перевод из ваулта)
|
||||
был **vaultPda** (владелец ATA), а не адрес аккаунта.
|
||||
|
||||
## НЕ делать
|
||||
- Не трогать логику ставок/цен.
|
||||
- Не трогать релейер (он уже передаёт правильный ATA-адрес).
|
||||
- Не коммитить.
|
||||
|
||||
## Проверка успеха
|
||||
- `anchor build` + IDL обновлён.
|
||||
- На localnet: передача `vault_token` = ATA (`getAssociatedTokenAddress(mint, vaultPda)`),
|
||||
create_bet принимает ставку, close_bet выплачивает (signer — vaultPda). E2E проходит.
|
||||
Reference in New Issue
Block a user