ton-community / disassembler

TON VM disassembler
MIT License
25 stars 5 forks source link

Invalid parsing of PUSHINT #8

Open ProgramCrafter opened 1 year ago

ProgramCrafter commented 1 year ago

PUSHINT 10 is shown as -6 PUSHINT.

Example contract: https://tonscan.org/address/EQArNPVIjXw_ffWPuGp_61zWtIH3tzBTBnHe9ToZ4m8OkoNf#source Code displayed on tonscan:

SETCP0
(:methods
  recv_internal: 

  recv_external: 
    3 BLKDROP
    10000000 PUSHINT
    LESS
    IFRET
    ACCEPT
    0 PUSHINT
    -6 PUSHINT
...

Code displayed on dton.io:

SETCP 0
DICTPUSHCONST 19, (xC_)
DICTIGETJMPZ {
  -1 => <{
    BLKDROP 3
    PUSHINT 10000000
    LESS
    IFRET
    ACCEPT
    PUSHINT 0
    PUSHINT 10
...

The relevant part of contract code uses only 10 and not -6:

() recv_external(int balance, int msg_value, cell msg_full, slice in_msg) {
  if (balance < 10 * 1000 * 1000) { return (); }
  accept_message();

  send_raw_message(begin_cell()
    .store_uint(0xA, 4)
  ...
ProgramCrafter commented 1 year ago

However, the most interesting thing is that 12 PUSHINT is handled correctly. This can be seen on https://tonscan.org/address/EQA-dgYSkIiw2J-MJ-0shgp1pzcmnoWo_vfd_240X7VDKuhf#source.

ProgramCrafter commented 1 year ago

This is related to incorrect handling of short ints.

According to TVM instructions, short PUSHINT

Pushes integer x into the stack. -5 <= x <= 10. Here i equals four lower-order bits of x (i=x mod 16).

https://github.com/ton-community/disassembler/blob/510270efc8c8ea66f4691954a59ba8a1655a9cb4/src/codepages/cp0.manual.ts#L60 And instruction handler just loads 4-bit int.