Opcode BLOCKHASH
for last 10 block numbers make starkent transaction revert
#3
Labels
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
duplicate-5
edited-by-warden
grade-b
Q-12
QA (Quality Assurance)
Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
🤖_primary
AI based primary recommendation
🤖_21_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/kkrt-labs/kakarot-ssj/blob/935c2238ac0b42c910afd3efeb96f003c1742edf/crates/contracts/src/cairo1_helpers.cairo#L153
Vulnerability details
Impact
When the opcode is
BLOCKHASH
( i.e0x40
), the cairo1_helpers.cairo::get_block_hash function is called ( interpreter.cairo::exec_opcode -> block_information.cairo::blockhash -> cairo1_helpers.cairo::get_block_hash )The cairo1_helpers.cairo::get_block_hash function is as follows :
This function uses
get_block_hash_syscall
to get the block hash of the specified block number but it return error if the block number is greater thancurrent block number - 10
as per the starknet docs. Whereas, as per the kakarot docs, it should return 0 for the blocks not available :So, rather than returning 0 as per the docs, it's using
unwrap_syscall()
which will make the transaction revert withFailure reason: 0x426c6f636b206e756d626572206f7574206f662072616e6765 ('Block number out of range')
.It also makes sense to return 0 for the blocks not available rather than reverting the starknet transaction which in EVM world, would forcefully revert the transaction. So any contract using
BLOCKHASH
opcode will be vulnerable to this issue or if a contract makes a callback to another contract by making sure to only send limited gas and handle the revert case properly, the other contract can useBLOCKHASH
opcode to make the transaction revert forcefully.Proof of Concept
Add this file named
test_kakarot_blockhash_bug.py
in kakarot/tests/end_to_end folder:You can run the test by:
After running
uv run deploy
, the block number will be 42 which can be seen in the first terminal where the nodes are running. And the test will execute theBLOCKHASH
opcode for the block number0x28
( i.e. 40 in decimals ) which is 2 blocks behind the current block number.This test will throw error as follows:
You can see the error
Block number out of range
which is due to theBLOCKHASH
opcode for last 10 block numbers.Tools Used
Python test suite
Recommended Mitigation Steps
It can be fixed by returning 0 rather than calling
unwrap_syscall()
in the cairo1_helpers.cairo::get_block_hash:NOTE: make sure to run
scarb build -p contracts
in kakarot-ssj folder and copy the files fromkakarot-ssj/target/dev
tokakarot/build/ssj
before running the test again.Assessed type
Error
The text was updated successfully, but these errors were encountered: