Commit 9131b3e
committed
fix: close-account missed discriminator in space calc
`basics/close-account/anchor` had `space = UserState::INIT_SPACE` in the `CreateUserContext` init constraint. Anchor does NOT auto-add the 8-byte account discriminator — `space` is passed literally to `system_program::create_account`. The correct form is always:
space = Struct::DISCRIMINATOR.len() + Struct::INIT_SPACE
UserState layout:
8 discriminator (required on every Anchor account, written before the struct body)
1 bump: u8
32 user: Pubkey
4 String length prefix
50 max_len name bytes
---
95 total bytes needed
87 INIT_SPACE (just the struct body, NO discriminator)
The old code allocated 87 bytes. On create, Anchor's `try_serialize` writes 8 discriminator bytes then up to 87 bytes of struct body using a `BpfWriter` over the account's data slice. With only 87 bytes of slice, that's 95 bytes into 87 bytes = short-write → `AccountDidNotSerialize`.
Why the existing test (`test_close_account.rs`) doesn't catch this: the test creates a user with name "John Doe" — 8 bytes of actual string plus the 4-byte length prefix = 12 bytes for the `name` field instead of the 54 bytes a max-length name would need. That gives an actual serialized size of 8 + 1 + 32 + 4 + 8 = 53 bytes, well under the 87-byte allocation. The bug only fires for names longer than 42 UTF-8 bytes — under the 50-byte advertised max.
Real bug. Fix verified with `cargo check --workspace`.
5th of 5 commits in the skill-audit cleanup.1 parent f334368 commit 9131b3e
1 file changed
Lines changed: 1 addition & 1 deletion
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | | - | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
0 commit comments