This file explains owner authority, trader PDAs, position authority, byte-level header checks, and key-risk evidence. Public protocol addresses are distinguished from account addresses; no individual account identifiers appear here.
TL;DR
- Owner wallet, trader PDA, and position authority are different identities.
- Solana base58 addresses are case-sensitive canonical 32-byte encodings.
- Verify binding from both signer identity and the raw on-chain trader header.
- Frozen or reduce-only capabilities describe restrictions, not a different owner.
- Delegate collateral risk is broader than permission names alone suggest; SwapNative analysis remains experimental.
1. Account model and base58
A trader PDA derives from owner authority, PDA index, subaccount index, and program. Subaccount zero is cross margin; nonzero subaccounts are isolated according to the SDK. Gate/onboarding restrictions and registration flows are outside the account-decoder implementation.
Preserve base58 case. Validate canonical decoding to exactly 32 bytes; a signature uses 64 decoded bytes. Lowercasing an address can identify another key or invalid bytes. Extra leading 1 characters add leading zero bytes and are not harmless formatting.
The ordinary trade instruction uses the owner's trader PDA while position authority signs. Do not derive a new trader account from the delegate key. Permission-account delegated instruction variants serve a different model and must not be substituted merely because a separate signer is present.
2. Trader header and capabilities
The 224-byte prefix uses the account discriminator sha256('account:trader')[0..8]. Verify that the Solana account owner is the Phoenix program before parsing. Relevant offsets are:
| Offset | Field |
|---|---|
| 56..88 | Owner authority |
| 88 | Signed i64 collateral quote lots |
| 96 | u32 capability bits |
| 112 | u32 maximum positions |
| 116 | u32 preference bits |
| 120..152 | Position authority |
| 154, 155 | PDA index, subaccount index |
Header layout was read on-chain on 2026-09-23 and 2026-09-24 and compared with public Rust source. Collateral is a balance, not portfolio equity; it can be negative.
Capability bits are HOT 1, LIMIT 2, MARKET 4, RISK 8, DEPOSIT 16, WITHDRAW 32. Zero is uninitialized; 62 is cold and 63 hot-active. Frozen and reduce-only combinations restrict risk-increasing actions according to protocol capability rules. Do not treat every restriction as lost delegation.
The first limit placement can activate a cold account inside that instruction. IoC need not activate it. Empty books and positions can return it to cold. These behaviors were observed or simulated on 2026-09-24; a successful cancel on cold may be a no-op.
3. Delegation and binding
DelegateTrader sets position authority and is signed by the owner, not the new delegate. Setting it back to owner resets delegation according to public program source. A registered trader account is required.
The experimental unsigned delegation builder takes the delegate as a caller argument, reads and validates the header, builds the owner-signable transaction, and can simulate without signature verification. Building or simulating it does not authorize signing/submission.
Compare signer health identity with expected owner, delegate, PDA, and indices, then independently parse the raw header. Wrong owner/program/PDA/index is a configuration error. A replaced or revoked delegate is confirmed binding loss. A failed read is unknown.
A binding gate starts unknown and blocks writes until delegation is verified. After a proved verdict, it retains that last known verdict when the next read fails; only confirmed loss changes it to lost, and only confirmed restoration changes it back. This does not make unknown information fresh, and current read availability remains separately reported.
4. Global configuration and key risk
Global-configuration decoding validates the program owner, discriminator, and prefix length before comparing REST transaction keys with on-chain fields. Public protocol constants are:
Program: EtrnLzgbS7nMMy5fbD42kXiUzGg8XQzJ972Xtk1cjWih
Log authority: GdxfTLSsdSY37G6fZoYtdGDSfgFnbT2EmRpuePZxWShS
Global configuration: 2zskx2iyCvb6Stg7RBZkt1f6MrF4dpYtMG3yMvKwqtUZ
These are public exchange accounts from Rise 0.5.28, not user wallets. Check current deployment constants before sending a transaction.
Experimental source analysis: public SwapNative code allows a position authority to invoke a native-collateral swap path subject to exchange/trader flags, withdrawal throttling, and margin checks. A signer-selected route/minimum output means “cannot call ordinary withdrawal” is not proof of harmlessness if the delegate is compromised. The attack path itself was not executed or independently demonstrated.
The trader preference disable_position_authority_swap is bit 1 << 1 at header preference offset 116. Exchange spot-collateral flags are read from global configuration; the disable-position-authority-swap bit is 1 << 2, while native SOL activation uses 1 << 0. The key-risk helper reports open/closed/unknown combinations with provenance instead of asserting a proven exploit.
Pitfalls
| What breaks | Why | Correct approach |
|---|---|---|
| Binding passes for another address | Address case normalized | Exact canonical base58 |
| Header data appears valid under another program | Owner/discriminator omitted | Validate both first |
| Frozen account called foreign | Capabilities mixed with identity | Separate restrictions and binding |
| Delegate assumes zero collateral risk | Ordinary withdrawal rules overgeneralized | Inspect source-based SwapNative verdict |
| Failed RPC clears a confirmed loss | Unknown overwrote verdict | Preserve last known state |
Open questions / not verified
- SwapNative attack feasibility in all capability/margin combinations.
- Delegate creation/funding of isolated child accounts.
- Whether the application replaces an existing position authority during a user action; always verify the header rather than infer the cause.
Sources
Accounts; Native SOL collateral; Rise public source (trader/global-configuration layout, capabilities, preferences, spot-collateral, native-SOL, and delegation Rust source). Public header/config checks: 2026-09-24. Key-risk verdict is experimental source analysis, not an observed drain.
© markpaper authors. Licensed under CC BY 4.0: when publishing or adapting this material, credit “markpaper — Phoenix knowledge base” and link to the original and the license.