-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gas charged after computation for precompiles may lead to running out of steps #20
Comments
Severity: Low Comment: Gas should be charged before running the computation. No clear attack path. |
dmvt marked the issue as unsatisfactory: |
Also overinflated severity |
Isn't this an issue:
Here the try/catch block in solidity or checking the return value of call in low level won't matter because the contract will revert on starknet level. So any contract can revert the whole transaction forcefully when it is called by other contracts. I want to know, what make this |
Specifically that you marked this high risk. See here: https://docs.code4rena.com/awarding/judging-criteria/severity-categorization#estimating-risk Ruling stands. |
"the function of the protocol or its availability could be impacted" right? So shouldn't it be at least medium? If you think it's low ( if yes, plz let me know why ), then I understand why you mark this as |
Severity is low. I agree with the sponsor. I will not comment further on this one. Ruling stands. |
dmvt marked the issue as not a duplicate |
dmvt changed the severity to QA (Quality Assurance) |
Lines of code
https://github.com/kkrt-labs/kakarot/blob/7411a5520e8a00be6f5243a50c160e66ad285563/src/kakarot/interpreter.cairo#L96
Vulnerability details
Impact
The interpreter.cairo::exec_opcode function is called whenever any opcode is executed. This function is as follows:
If the precompile is going to take a lot of gas ( which can be precalculated ), then rather than charging high gas, the transaction would revert due to running out of steps. As it can consume more than
10,000,000
whereas the max steps allowed is10,000,000
as per starknet docs ( refer: Max transaction size (Cairo steps) ). So in mainnet, this transaction will revert due toout of steps
error.So any contract using precompiles 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 call the precompile with such a data that will consume a lot of gas which will make the transaction revert forcefully. Plus, the contract doesn't even need to send a lot of gas ( or may only send
0
gas ) while makingSTATICCALL
to precompile.Proof of Concept
Consider
blake2f
precompile which charges gas as follows:So if the number of rounds is very large, then the gas charged will also be very high but the transaction will revert due to running out of steps thus it won't charge any gas even if zero gas was send while calling the precompile using
STATICCALL
opcode.NOTE: First 4 bytes ( out of 213 bytes ) in the calldata is the number of rounds.
So consider the following code:
Save the above code in a file name
blake2f.huff
( You can refer Installing Huff, if you don't have huff installed ).The above code will call the precompile
blake2f
where number of rounds will0xffffffff
(4294967295
) and we're sending0
gas and in reality it should revert at evm level due to out of gas error.The above code can be converted to bytecode using the following command:
The output will be:
The runtime code is ( after removing the first few bytes which are responsible for deployment ):
Add the following cairo file named
test_kakarot_blake2f.cairo
in kakarot/tests/src/kakarot folder:Also add the following python test file named
test_kakarot_blake2f.py
in the same folder i.e kakarot/tests/src/kakarot folder:Now run the test using the following command:
The test will take very long time ( due to speed of python ) before throwing error that the transaction ran out of steps ( n_steps=10_000_000 ) which will be something like:
NOTE: You can print number of steps by adding the print statement in kakarot/tests/fixtures/starknet.py:
Although it won't print the steps as the transaction will revert before that.
Tools Used
Python test suite
Recommended Mitigation Steps
As the total cost for the precompile can be precalculated, it should be charged before executing the precompile. For some precompile, if they're reverted then all the gas is charged thus this case should also be considered while executing the revert code. So if enough gas isn't sent, the transaction would revert at evm level rather than running out of steps.
Assessed type
Other
The text was updated successfully, but these errors were encountered: