-
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
Account contract does not gracefully handle panics in called contracts #49
Comments
Severity: Informative Comment: This is a know limitation of starknet. It is not a problem as relayer can decide to not relay the tx. |
dmvt changed the severity to 2 (Med Risk) |
I find it hard to look at this as anything other than an impact to expected functionality / availability of functionality, making the severity medium. As shown above, this is likely to be encountered often with very standard functionality, much of which is included in OZ EVM implementations of common token patterns. The potential for novel uses of this dynamic to cause hypothetical exploits or denial of service attacks doesn't seem like something that should be ignored or written off to a "limitation of starknet". |
dmvt marked the issue as selected for report |
To summarize
let's keep it medium |
…proofness (#1625) Uses a call to the Cairo1Helpers class to access the "new" call_contract syscall, that will __in the future__ have the ability to gracefully handle failed contract calls. NOTE: The change implemented in the following PR does not fix [KGA-19] (code-423n4/2024-09-kakarot-findings#49) because the Starknet network does not allow handling failed calls yet. Attention to reviewer: The change to the Cairo1Helpers class needs to be merged in kakarot-ssj first. Discussion can be made here
Lines of code
https://github.com/kkrt-labs/kakarot/blob/7411a5520e8a00be6f5243a50c160e66ad285563/src/kakarot/accounts/account_contract.cairo#L347
Vulnerability details
The
DualVmToken
is a utility EVM contract allowing Kakarot EVM accounts to operate Starknet ERC-20s via classicbalanceOf()
,transfer()
etc. operations.Calls to the
DualVmToken
contract are routed viaCairoLib
->kakarot_precompiles.cairo
->account_contract.cairo
, which finally makes a call to thecall_contract()
Cairo 0 syscall to invoke the appropriate Starknet ERC-20 contract.If we look at how the
execute_starknet_call()
function inaccount_countract.cairo
is implemented:we see that the function admits graceful failures (by returning a
success: felt
value that can beFALSE
), which are then properly handled in the calling precompile. However, the actual call to the target contract (at L347) does not return asuccess
boolean, and instead uses thecall_contract
syscall which panics on failures.This means that any call that panics in the called contract can cause a revert at RPC level.
To illustrate how this is not a hypothetical scenario, but a very likely one that can be achieved also with the DualVmToken contract that is in scope and consequently planned to be whitelisted to make this call, we make a simple example:
In this scenario, standard OpenZeppelin ERC-20 implementations panic, bubbling up the error up to the Kakarot RPC level.
This also means that most of the ERC-20 behaviours Kakarot intends to support will lead to reverts at the RPC level if encountered. The following table shows the effect of each behaviour if encountered in a call to a
DualVmToken
:Impact
Any contract can use the above "over-transfer" call to cause RPC-level crashes in the Kakarot EVM, regardless of how defensively they were called. Protective measures generally considered safe in the EVM space like ExcessivelySafeCall (which is used in LayerZero cross-chain applications to prevent channel DoSes that can permanently freeze in-flight tokens), can be bypassed by causing a RPC-level cairo revert.
More generally, any transaction containing a call to a reverting
DualVmToken
at any depth will revert. This means contracts whose logic requires such a call to succeed will be temporarily (if the call eventually succeeds) or permanently bricked.Proof of Concept
The RPC-level panic can be proved by simply editing the
test_should_transfer
intest_dual_vm_token.py
end-to-end test to transferbalance_owner_before + amount
instead ofamount
at L110.Recommended Mitigation Steps
The new
AccountContract
Cairo 1 implementation uses the Cairo 1call_contract
syscall, which offers a recoverable error interface through anopanic
signature returning a Result. If it is not possible to deploy the new version, the Cairo 1 syscall can be used from the Cairo 0account_contract
via a library call as is done with other functionality.Assessed type
Other
The text was updated successfully, but these errors were encountered: