@@ -5,21 +5,36 @@ import Testing
55@Suite ( " CoinbaseStableSwapperProgram.PoolAccount " )
66struct CoinbaseStableSwapperPoolAccountTests {
77
8- /// Minimum account length: 8 discriminator + 32 ops authority
9- /// + 32 pause authority + 32 fee recipient.
10- private static let minimumLength = 8 + 32 + 32 + 32
11-
12- private static func accountData( feeRecipient: [ UInt8 ] , trailing: Int = 0 ) -> Data {
13- var data = Data ( repeating: 0xAA , count: 8 ) // discriminator
14- data. append ( Data ( repeating: 0xBB , count: 32 ) ) // operations authority
15- data. append ( Data ( repeating: 0xCC , count: 32 ) ) // pause authority
8+ /// `sha256("account:LiquidityPool")[0..8]` — the real Anchor discriminator for this account.
9+ private static let discriminator : [ UInt8 ] = [ 66 , 38 , 17 , 64 , 188 , 80 , 68 , 129 ]
10+
11+ /// Minimum account length: 8 discriminator + 32 operations authority + 32 pause authority
12+ /// + 32 unnamed pubkey + 32 unnamed pubkey + 32 fee recipient.
13+ private static let minimumLength = 8 + 32 + 32 + 32 + 32 + 32
14+
15+ /// Base64 of the first 168 bytes (discriminator through `fee_recipient`) of the real
16+ /// pool account `CrDL9SoCyW1tBgn8k7rgGSpWhnszneWDbvKvqPAU4PL9`, captured from mainnet.
17+ private static let realCapturedAccountDataBase64 = """
18+ QiYRQLxQRIEFHqE9vluQFKO1wbEwnd22aRe9qGrV03SIsz1AV7GqT/yEzcR/f+ALaKG4KMxbBfZ5dTNFPqxxZHMfbTqNfj6St0p++yObz2IILMcKsoko07O+oRSDek7YwzrH9TroL1+QbHdT/t9qpcq4Kyx8OPWZm79AIUM9UlN+X6ujF0hPgzT4z8SXtrVTfBhZj7LzSPTgCpHoi6cjfPqXvflOJvRB
19+ """
20+
21+ private static func accountData(
22+ feeRecipient: [ UInt8 ] ,
23+ discriminator: [ UInt8 ] = Self . discriminator,
24+ trailing: Int = 0
25+ ) -> Data {
26+ var data = Data ( discriminator)
27+ data. append ( Data ( repeating: 0xBB , count: 32 ) ) // operations_authority
28+ data. append ( Data ( repeating: 0xCC , count: 32 ) ) // pause_authority
29+ data. append ( Data ( repeating: 0xEE , count: 32 ) ) // unnamed pubkey (offset 72)
30+ data. append ( Data ( repeating: 0xFA , count: 32 ) ) // unnamed pubkey (offset 104)
1631 data. append ( Data ( feeRecipient) )
1732 data. append ( Data ( repeating: 0xDD , count: trailing) )
1833 return data
1934 }
2035
2136 @Test (
22- " Parses the fee recipient at offset 72 , with or without trailing fields " ,
37+ " Parses the fee recipient at offset 136 , with or without trailing fields " ,
2338 arguments: [ 0 , 128 ]
2439 )
2540 func initAccountData_validLayout_parsesFeeRecipient( trailing: Int ) throws {
@@ -32,10 +47,28 @@ struct CoinbaseStableSwapperPoolAccountTests {
3247 #expect( account. feeRecipient == ( try PublicKey ( feeRecipientBytes) ) )
3348 }
3449
50+ @Test ( " Decodes the real pool account and recovers the correct fee recipient " )
51+ func initAccountData_realCapturedAccount_parsesFeeRecipient( ) throws {
52+ let data = try #require( Data ( base64Encoded: Self . realCapturedAccountDataBase64) )
53+ let account = try #require( CoinbaseStableSwapperProgram . PoolAccount ( accountData: data) )
54+ #expect( account. feeRecipient == ( try PublicKey ( base58: " 4ZnFXk7KyB5khDqjWSHqHBQH1nQCnmvkr1pRFivWcP7e " ) ) )
55+ }
56+
3557 @Test ( " Rejects account data shorter than the fee recipient bounds " )
3658 func initAccountData_shortData_returnsNil( ) {
37- let short = Data ( repeating: 0xAA , count: Self . minimumLength - 1 )
38- #expect( CoinbaseStableSwapperProgram . PoolAccount ( accountData: short) == nil )
59+ let short = Self . accountData ( feeRecipient: [ UInt8] ( repeating: 7 , count: 32 ) )
60+ . prefix ( Self . minimumLength - 1 )
61+ #expect( CoinbaseStableSwapperProgram . PoolAccount ( accountData: Data ( short) ) == nil )
62+ }
63+
64+ @Test ( " Rejects a discriminator that doesn't match LiquidityPool " )
65+ func initAccountData_mismatchedDiscriminator_returnsNil( ) {
66+ let wrongDiscriminator = [ UInt8] ( repeating: 0 , count: 8 )
67+ let data = Self . accountData (
68+ feeRecipient: [ UInt8] ( repeating: 7 , count: 32 ) ,
69+ discriminator: wrongDiscriminator
70+ )
71+ #expect( CoinbaseStableSwapperProgram . PoolAccount ( accountData: data) == nil )
3972 }
4073
4174 @Test ( " Ignores slice offsets — parses relative to the data's start " )
0 commit comments