|
12 | 12 | from pyk.ktool.kprove import KProve
|
13 | 13 | from pyk.ktool.krun import KRun
|
14 | 14 | from pyk.prelude.kint import intToken, ltInt
|
15 |
| -from pyk.prelude.ml import mlEqualsTrue |
| 15 | +from pyk.prelude.ml import mlEqualsFalse, mlEqualsTrue |
16 | 16 | from pyk.prelude.string import stringToken
|
17 | 17 | from pyk.proof.reachability import APRBMCProof, APRProof
|
18 | 18 | from pyk.proof.show import APRBMCProofNodePrinter, APRProofNodePrinter
|
@@ -242,16 +242,39 @@ def short_info(self, cterm: CTerm) -> list[str]:
|
242 | 242 |
|
243 | 243 | @staticmethod
|
244 | 244 | def add_invariant(cterm: CTerm) -> CTerm:
|
| 245 | + def _add_account_invariant(account: KApply) -> list[KApply]: |
| 246 | + _account_constraints = [] |
| 247 | + acct_id, balance, nonce = account.args[0], account.args[1], account.args[5] |
| 248 | + |
| 249 | + if type(acct_id) is KApply and type(acct_id.args[0]) is KVariable: |
| 250 | + _account_constraints.append(mlEqualsTrue(KEVM.range_address(acct_id.args[0]))) |
| 251 | + _account_constraints.append( |
| 252 | + mlEqualsFalse(KEVM.is_precompiled_account(acct_id.args[0], cterm.cell('SCHEDULE_CELL'))) |
| 253 | + ) |
| 254 | + if type(balance) is KApply and type(balance.args[0]) is KVariable: |
| 255 | + _account_constraints.append(mlEqualsTrue(KEVM.range_uint(256, balance.args[0]))) |
| 256 | + if type(nonce) is KApply and type(nonce.args[0]) is KVariable: |
| 257 | + _account_constraints.append(mlEqualsTrue(KEVM.range_nonce(nonce.args[0]))) |
| 258 | + return _account_constraints |
| 259 | + |
245 | 260 | constraints = []
|
246 | 261 | word_stack = cterm.cell('WORDSTACK_CELL')
|
247 | 262 | if type(word_stack) is not KVariable:
|
248 | 263 | word_stack_items = flatten_label('_:__EVM-TYPES_WordStack_Int_WordStack', word_stack)
|
249 | 264 | for i in word_stack_items[:-1]:
|
250 | 265 | constraints.append(mlEqualsTrue(KEVM.range_uint(256, i)))
|
251 | 266 |
|
252 |
| - gas_cell = cterm.cell('GAS_CELL') |
253 |
| - if not (type(gas_cell) is KApply and gas_cell.label.name == 'infGas'): |
254 |
| - constraints.append(mlEqualsTrue(KEVM.range_uint(256, gas_cell))) |
| 267 | + accounts_cell = cterm.cell('ACCOUNTS_CELL') |
| 268 | + if type(accounts_cell) is not KApply('.AccountCellMap'): |
| 269 | + accounts = flatten_label('_AccountCellMap_', cterm.cell('ACCOUNTS_CELL')) |
| 270 | + for wrapped_account in accounts: |
| 271 | + if not (type(wrapped_account) is KApply and wrapped_account.label.name == 'AccountCellMapItem'): |
| 272 | + continue |
| 273 | + |
| 274 | + account = wrapped_account.args[1] |
| 275 | + if type(account) is KApply: |
| 276 | + constraints.extend(_add_account_invariant(account)) |
| 277 | + |
255 | 278 | constraints.append(mlEqualsTrue(KEVM.range_address(cterm.cell('ID_CELL'))))
|
256 | 279 | constraints.append(mlEqualsTrue(KEVM.range_address(cterm.cell('CALLER_CELL'))))
|
257 | 280 | constraints.append(mlEqualsTrue(KEVM.range_address(cterm.cell('ORIGIN_CELL'))))
|
@@ -315,6 +338,10 @@ def range_bool(i: KInner) -> KApply:
|
315 | 338 | def range_bytes(width: KInner, ba: KInner) -> KApply:
|
316 | 339 | return KApply('#rangeBytes(_,_)_WORD_Bool_Int_Int', [width, ba])
|
317 | 340 |
|
| 341 | + @staticmethod |
| 342 | + def range_nonce(i: KInner) -> KApply: |
| 343 | + return KApply('#rangeNonce(_)_WORD_Bool_Int', [i]) |
| 344 | + |
318 | 345 | @staticmethod
|
319 | 346 | def range_blocknum(ba: KInner) -> KApply:
|
320 | 347 | return KApply('#rangeBlockNum(_)_WORD_Bool_Int', [ba])
|
@@ -343,6 +370,10 @@ def bin_runtime(c: KInner) -> KApply:
|
343 | 370 | def init_bytecode(c: KInner) -> KApply:
|
344 | 371 | return KApply('initBytecode', [c])
|
345 | 372 |
|
| 373 | + @staticmethod |
| 374 | + def is_precompiled_account(i: KInner, s: KInner) -> KApply: |
| 375 | + return KApply('#isPrecompiledAccount(_,_)_EVM_Bool_Int_Schedule', [i, s]) |
| 376 | + |
346 | 377 | @staticmethod
|
347 | 378 | def hashed_location(compiler: str, base: KInner, offset: KInner, member_offset: int = 0) -> KApply:
|
348 | 379 | location = KApply(
|
|
0 commit comments