Slightly wrong concrete transaction data in multi-tx & multi-contract (delegatecall) scenario
See original GitHub issueDescription
Running Mythril on a relatively complex example appears to detect the correct bug, but returns slightly wrong concrete transaction data to reach it. Here is the code:
pragma solidity ^0.4.24;
contract EvilDelegate {
bool xyz;
function abc() public {
// do nothing
xyz = false;
}
}
contract Wallet {
bool private initialized = false;
address public owner;
EvilDelegate private _delegate;
constructor(address _delegateAddress) public {
_delegate = EvilDelegate(_delegateAddress);
}
// The owner can only be set once during initialization.
function initWallet() public {
require(initialized == false);
initialized = true;
owner = msg.sender;
}
// Dangerous! Can only be called by the owner!
function kill() public {
require(msg.sender == owner);
selfdestruct(msg.sender);
}
function() public payable {
if (msg.data.length > 0) {
_delegate.delegatecall(msg.data);
}
}
}
Wallet is deployed on Ropsten with address 0xc2e75b81d21831c3bf6a739c3b1495c33045d258 and the owner has been initialized to 0x0583858adfe7d1d3DC7F8447301cf7B7b056d638.
Mythril output is as follows:
$ $MYTH --rpc infura-ropsten -msuicide -xla 0xc2e75b81d21831c3bf6a739c3b1495c33045d258 --transaction-count 3 --verbose-report
==== Unchecked SUICIDE ====
SWC ID: 106
Type: Warning
Contract: 0xc2e75b81d21831c3bf6a739c3b1495c33045d258
Function name: kill()
PC address: 572
A reachable SUICIDE instruction was detected. The remaining Ether is sent to the caller's address.
--------------------
--------------------
DEBUGGING INFORMATION:
Transaction Sequence: {'1': {'calldata': '0x00', 'call_value': None, 'caller': '0x0000000000000000000000000000000000000001'}, '6': {'calldata': '0x3e326048', 'call_value': '0x0', 'caller': '0x0000000000000000000000000000000000000001'}, '16': {'calldata': '0x41c0e1b5', 'call_value': '0x0', 'caller': '0x0000000000000000000000000000000000000001'}}
Expected behavior
Theoretically the correct call data for the 3-tx “exploitation” sequence is:
- ‘0x92277933’ -> call
abc()
which is forwarded through the delegate call proxy and setsinitialized
tofalse
- ‘0x3e326048’ -> call
initWallet()
which setowner
tomsg.sender
- ‘0x41c0e1b5’ -> call
kill()
The output produced by Mythril is:
- ‘0x00’ -> empty calldata
- ‘0x3e326048’ -> call
initWallet()
which setowner
tomsg.sender
- ‘0x41c0e1b5’ -> call
kill()
Might be something wrong in processing calldata passed between contracts in the delegatecall, or an issue resolving storage.
Note that without the -l
flag no issue is detected (which is expected behavior).
Environment
- Mythril version: Develop
- Python version:
python -V
- OS and Version: Mac OS Mojave
Issue Analytics
- State:
- Created 5 years ago
- Comments:6 (6 by maintainers)
Top Results From Across the Web
Dynamic loader does not retrieve map items #1176 - GitHub
Mythril on-chain analysis is unable to dynamically retrieve the content of map items from the blockchain, resulting in false positives.
Read more >Gnosis Safe: Unexpected Delegate call while sending multiple ...
Due to security reasons this warning is shown if a multisend contract is used that is not "known" by our services. As delegatecalls...
Read more >Multi Delegatecall | Solidity 0.8 - YouTube
Batch transactions with multi delegatecall.#Solidity #SmartContract #Ethereum #スマートコントラクトRemixhttps://remix.ethereum.
Read more >Mythril Documentation - Read the Docs
This module contains the detection code to find multiple sends occurring in a single transaction. class mythril.analysis.module.modules.
Read more >An Automatic Repair Framework for On-Chain Smart Contracts
The core insight of Aroc is to generate patch contracts to abort malicious transactions in advance. Taking the three most serious bug types...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I’m finally able to reproduce. I found various regressions before being able to:
I’ll try to come up with fixes for these, and then fix the actual problem. Also I think the current behavior is not so bad: better to unconstrain the input so we catch the bug, even if it’s slightly wrong.
https://github.com/ConsenSys/mythril-classic/pull/739 and #693 have been closed. Some good progress, but not good enough and they don’t fix the issue.