@@ -897,54 +897,89 @@ Only the system Rent will be stored as a value directly. The `SysRent` wrapper i
897897 syntax Value ::= SysRent ( PRent )
898898```
899899
900- ``` {.k .symbolic}
900+ Note that in case of the system-global ` Rest ` , it is important to always return _ the same_ symbolic value.
901+ Therefore, the value gets created in a dedicated place on first access.
902+
903+ ``` k
901904 rule [cheatcode-get-sys-prent]:
902905 <k> #execTerminator(terminator(terminatorKindCall(FUNC, .Operands, DEST, someBasicBlockIdx(TARGET), _UNWIND), _SPAN))
903- => #setLocalValue(
904- DEST,
905- Aggregate(variantIdx(0), // returns a Result type
906- ListItem(
906+ => #writeSysRent(DEST)
907+ ~> #execBlockIdx(TARGET)
908+ ...
909+ </k>
910+ requires #functionName(lookupFunction(#tyOfCall(FUNC))) ==String "<sysvars::rent::Rent as sysvars::Sysvar>::get"
911+ [priority(30), preserves-definedness]
912+
913+ syntax KItem ::= #writeSysRent ( Place )
914+ ```
915+
916+ If the system-global ` SysRent ` has already been created, it is simplify written to the destination (in a ` Result ` type).
917+ The ` SysRent ` is stored in the outermost stack frame's return slot (local _ 0), which is otherwise unused as there is no caller to return to.
918+
919+ ``` k
920+ rule <k> #writeSysRent(DEST) => #setLocalValue(DEST, Aggregate(variantIdx(0), ListItem(SYSRENT))) ... </k>
921+ <stack>
922+ STACK:List // sys-rent is stored in the outermost stack frame's return slot (local _0)
923+ ListItem(StackFrame(_, _, _, _, ListItem(typedValue(SysRent(_) #as SYSRENT, _, _)) _REST))
924+ </stack>
925+ requires 0 <Int size(STACK)
926+ [preserves-definedness]
927+
928+ rule <k> #writeSysRent(DEST) => #setLocalValue(DEST, Aggregate(variantIdx(0), ListItem(SYSRENT))) ... </k>
929+ <stack> // singleton case
930+ ListItem(StackFrame(_, _, _, _, ListItem(typedValue(SysRent(_) #as SYSRENT, _, _)) _REST))
931+ </stack>
932+ [preserves-definedness]
933+ ```
934+ If this is the first access to the ` SysRent ` , it will be created (symbolically or using random values).
935+
936+ ``` {.k .symbolic}
937+ rule [mk-sys-prent]:
938+ <k> #writeSysRent(_DEST) ~> _CONT </k>
939+ <stack>
940+ _:List
941+ ListItem(StackFrame(_, _, _, _,
942+ ListItem(newLocal(_, _) =>
943+ typedValue(
907944 SysRent(
908945 PRent(
909946 U64(?SYS_LMP_PER_BYTEYEAR),
910947 F64(2.0), // fixed exempt_threshold 2.0 (default)
911948 U8(?SYS_BURN_PCT)
912949 )
913- )
950+ ),
951+ ty(0),
952+ mutabilityNot
914953 )
915- )
916- )
917- ~> #execBlockIdx(TARGET)
918- ...
919- </k>
920- requires #functionName(lookupFunction(#tyOfCall(FUNC))) ==String "<sysvars::rent::Rent as sysvars::Sysvar>::get"
954+ ) _:List
955+ ))
956+ </stack>
921957 ensures 0 <=Int ?SYS_LMP_PER_BYTEYEAR andBool ?SYS_LMP_PER_BYTEYEAR <Int 1 <<Int 32 // limited arbitrarily to avoid overflows on fixed concrete values
922958 andBool 0 <=Int ?SYS_BURN_PCT andBool ?SYS_BURN_PCT <=Int 100 // limited so that it is a true percentage
923- [priority(30), preserves-definedness]
959+ [preserves-definedness]
924960```
925961
926962``` {.k .concrete}
927- rule [cheatcode-get-sys-prent]:
928- <k> #execTerminator(terminator(terminatorKindCall(FUNC, .Operands, DEST, someBasicBlockIdx(TARGET), _UNWIND), _SPAN))
929- => #setLocalValue(
930- DEST,
931- Aggregate(variantIdx(0), // returns a Result type
932- ListItem(
963+ rule [mk-sys-prent]:
964+ <k> #writeSysRent(_DEST) ~> _CONT </k>
965+ <stack>
966+ _:List
967+ ListItem(StackFrame(_, _, _, _,
968+ ListItem(newLocal(_, _) =>
969+ typedValue(
933970 SysRent(
934971 PRent(
935972 U64(#randU64()), // sys_lmp_per_byteyear
936973 F64(#randExemptThreshold()), // sys_exempt_threshold
937974 U8(#randU8()) // sys_burn_pct
938975 )
939- )
976+ ),
977+ ty(0),
978+ mutabilityNot
940979 )
941- )
942- )
943- ~> #execBlockIdx(TARGET)
944- ...
945- </k>
946- requires #functionName(lookupFunction(#tyOfCall(FUNC))) ==String "<sysvars::rent::Rent as sysvars::Sysvar>::get"
947- [priority(30)]
980+ ) _:List
981+ ))
982+ </stack>
948983```
949984
950985### Access to the ` Rent ` struct
0 commit comments