Skip to content

Commit 4d819f7

Browse files
authored
feat(spl): support cheatcode_is_spl_mint and refine the mock test program (#858)
- Refine the mock program to test all the domain data in SPL Token; - Add cheatcode support for Mint, because it is similar to Account.
1 parent a6dc6f1 commit 4d819f7

File tree

3 files changed

+487
-37
lines changed

3 files changed

+487
-37
lines changed

kmir/src/kmir/kdist/mir-semantics/symbolic/spl-token.md

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Account::pack(a, &mut acc.data.borrow_mut())
2222
-> #isSPLBorrowFunc (rule [spl-borrow-data])
2323
-> #isSPLRefDerefFunc (rule [spl-ref-deref])
2424
-> Borrowed buffer projections
25-
-> #isSPLAccountUnpackFunc / #isSPLAccountPackFunc (rule [spl-account-unpack])
25+
-> #isSPLUnpackFunc / #isSPLPackFunc (rule [spl-account-unpack])
2626
```
2727

2828

@@ -133,18 +133,29 @@ module KMIR-SPL-TOKEN
133133
rule #isSPLRefDerefFunc("<std::cell::RefMut<'_, &mut [u8]> as std::ops::DerefMut>::deref_mut") => true
134134
rule #isSPLRefDerefFunc(_) => false [owise]
135135
136-
syntax Bool ::= #isSPLAccountUnpackFunc ( String ) [function, total]
137-
rule #isSPLAccountUnpackFunc(_) => false [owise]
138-
rule #isSPLAccountUnpackFunc("solana_program_pack::<spl_token_interface::state::Account as solana_program_pack::Pack>::unpack_unchecked") => true
139-
rule #isSPLAccountUnpackFunc("solana_program_pack::<spl_token_interface::state::Account as solana_program_pack::Pack>::unpack") => true
140-
// mock
141-
rule #isSPLAccountUnpackFunc("Account::unpack_unchecked") => true
142-
143-
syntax Bool ::= #isSPLAccountPackFunc ( String ) [function, total]
144-
rule #isSPLAccountPackFunc(_) => false [owise]
145-
rule #isSPLAccountPackFunc("solana_program_pack::<spl_token_interface::state::Account as solana_program_pack::Pack>::pack") => true
146-
// mock
147-
rule #isSPLAccountPackFunc("Account::pack") => true
136+
syntax Bool ::= #isSPLUnpackFunc ( String ) [function, total]
137+
rule #isSPLUnpackFunc(_) => false [owise]
138+
// spl-token account
139+
rule #isSPLUnpackFunc("solana_program_pack::<spl_token_interface::state::Account as solana_program_pack::Pack>::unpack_unchecked") => true
140+
rule #isSPLUnpackFunc("solana_program_pack::<spl_token_interface::state::Account as solana_program_pack::Pack>::unpack") => true
141+
// mock account
142+
rule #isSPLUnpackFunc("Account::unpack_unchecked") => true
143+
// spl-token mint
144+
rule #isSPLUnpackFunc("solana_program_pack::<spl_token_interface::state::Mint as solana_program_pack::Pack>::unpack_unchecked") => true
145+
rule #isSPLUnpackFunc("solana_program_pack::<spl_token_interface::state::Mint as solana_program_pack::Pack>::unpack") => true
146+
// mock mint
147+
rule #isSPLUnpackFunc("Mint::unpack_unchecked") => true
148+
149+
syntax Bool ::= #isSPLPackFunc ( String ) [function, total]
150+
rule #isSPLPackFunc(_) => false [owise]
151+
// spl-token account
152+
rule #isSPLPackFunc("solana_program_pack::<spl_token_interface::state::Account as solana_program_pack::Pack>::pack") => true
153+
// mock account
154+
rule #isSPLPackFunc("Account::pack") => true
155+
// spl-token mint
156+
rule #isSPLPackFunc("solana_program_pack::<spl_token_interface::state::Mint as solana_program_pack::Pack>::pack") => true
157+
// mock mint
158+
rule #isSPLPackFunc("Mint::pack") => true
148159
```
149160

150161

@@ -210,6 +221,60 @@ module KMIR-SPL-TOKEN
210221
andBool #isSplCOptionPubkey(?SplCloseAuthCOpt)
211222
andBool #isSplCOptionU64(?SplIsNativeCOpt)
212223
[priority(30), preserves-definedness]
224+
225+
rule [cheatcode-is-spl-mint]:
226+
<k> #execTerminator(terminator(terminatorKindCall(FUNC, operandCopy(place(LOCAL, PROJS)) .Operands, _DEST, someBasicBlockIdx(TARGET), _UNWIND), _SPAN))
227+
=> #setLocalValue(
228+
place(LOCAL, appendP(PROJS, projectionElemDeref .ProjectionElems)),
229+
Aggregate(variantIdx(0),
230+
ListItem(Range(?SplMintAccountKey:List))
231+
ListItem(
232+
SPLRefCell(
233+
place(
234+
LOCAL,
235+
appendP(PROJS, projectionElemDeref projectionElemField(fieldIdx(1), #hack()) .ProjectionElems)
236+
),
237+
Integer(?SplMintLamports:Int, 64, false)
238+
)
239+
)
240+
ListItem(
241+
SPLRefCell(
242+
place(
243+
LOCAL,
244+
appendP(PROJS, projectionElemDeref projectionElemField(fieldIdx(2), #hack()) .ProjectionElems)
245+
),
246+
SPLDataBuffer(
247+
Aggregate(variantIdx(0),
248+
ListItem(?SplMintAuthorityCOpt:Value)
249+
ListItem(Integer(?SplMintSupply:Int, 64, false))
250+
ListItem(Integer(?SplMintDecimals:Int, 8, false))
251+
ListItem(BoolVal(false))
252+
ListItem(?SplMintFreezeAuthorityCOpt:Value)
253+
)
254+
)
255+
)
256+
)
257+
ListItem(Range(?SplMintOwnerKey:List))
258+
ListItem(Integer(?SplMintRentEpoch:Int, 64, false))
259+
ListItem(BoolVal(?_SplMintIsSigner:Bool))
260+
ListItem(BoolVal(?_SplMintIsWritable:Bool))
261+
ListItem(BoolVal(?_SplMintExecutable:Bool))
262+
)
263+
)
264+
~> #execBlockIdx(TARGET)
265+
...
266+
</k>
267+
requires #functionName(lookupFunction(#tyOfCall(FUNC))) ==String "spl_token::entrypoint::cheatcode_is_spl_mint"
268+
orBool #functionName(lookupFunction(#tyOfCall(FUNC))) ==String "cheatcode_is_spl_mint"
269+
ensures #isSplPubkey(?SplMintAccountKey)
270+
andBool #isSplPubkey(?SplMintOwnerKey)
271+
andBool 0 <=Int ?SplMintLamports andBool ?SplMintLamports <Int 18446744073709551616
272+
andBool 0 <=Int ?SplMintRentEpoch andBool ?SplMintRentEpoch <Int 18446744073709551616
273+
andBool #isSplCOptionPubkey(?SplMintAuthorityCOpt)
274+
andBool 0 <=Int ?SplMintSupply andBool ?SplMintSupply <Int (1 <<Int 64)
275+
andBool 0 <=Int ?SplMintDecimals andBool ?SplMintDecimals <Int 256
276+
andBool #isSplCOptionPubkey(?SplMintFreezeAuthorityCOpt)
277+
[priority(30), preserves-definedness]
213278
```
214279

215280
## Accessing `Rc<RefCell<_>>`
@@ -451,7 +516,7 @@ expose the wrapped payload directly.
451516
~> #execBlockIdx(TARGET)
452517
...
453518
</k>
454-
requires #isSPLAccountUnpackFunc(#functionName(lookupFunction(#tyOfCall(FUNC))))
519+
requires #isSPLUnpackFunc(#functionName(lookupFunction(#tyOfCall(FUNC))))
455520
[priority(30), preserves-definedness]
456521
457522
syntax KItem ::= #mkSPLAccountUnpack ( Place , Evaluation ) [seqstrict(2)]
@@ -496,7 +561,7 @@ expose the wrapped payload directly.
496561
~> #execBlockIdx(TARGET)
497562
...
498563
</k>
499-
requires #isSPLAccountPackFunc(#functionName(lookupFunction(#tyOfCall(FUNC))))
564+
requires #isSPLPackFunc(#functionName(lookupFunction(#tyOfCall(FUNC))))
500565
[priority(30), preserves-definedness]
501566
502567
syntax KItem ::= #mkSPLAccountPack ( Evaluation , Evaluation , Place ) [seqstrict(1,2)]

0 commit comments

Comments
 (0)