mirror of https://github.com/crytic/echidna
Commit f1f45d3c0d9767a38df04f398d1eab8b66dbe7fc Includes fixes and new cheatcodes.
parent
b54afcda5f
commit
298150fffc
@ -0,0 +1,31 @@ |
|||||||
|
pragma experimental ABIEncoderV2; |
||||||
|
|
||||||
|
interface Hevm { |
||||||
|
function setEnv(string calldata, string calldata) external; |
||||||
|
function ffi(string[] calldata) external returns (bytes memory); |
||||||
|
} |
||||||
|
|
||||||
|
contract TestFFI { |
||||||
|
address constant HEVM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; |
||||||
|
|
||||||
|
bytes32 hehe; |
||||||
|
|
||||||
|
function foo(int x) external { |
||||||
|
// ABI encoded "gm", as a string |
||||||
|
Hevm(HEVM_ADDRESS).setEnv("ECHIDNA_FOO_BAR", "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002676d000000000000000000000000000000000000000000000000000000000000"); |
||||||
|
|
||||||
|
string[] memory inputs = new string[](3); |
||||||
|
inputs[0] = "sh"; |
||||||
|
inputs[1] = "-c"; |
||||||
|
inputs[2] = "printf '%s' \"$ECHIDNA_FOO_BAR\""; |
||||||
|
|
||||||
|
bytes memory res = Hevm(HEVM_ADDRESS).ffi(inputs); |
||||||
|
|
||||||
|
(string memory output) = abi.decode(res, (string)); |
||||||
|
hehe = keccak256(bytes(output)); |
||||||
|
} |
||||||
|
|
||||||
|
function echidna_ffi() public returns (bool){ |
||||||
|
return hehe != keccak256("gm"); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,46 @@ |
|||||||
|
pragma experimental ABIEncoderV2; |
||||||
|
|
||||||
|
interface Hevm { |
||||||
|
function assume(bool) external; |
||||||
|
} |
||||||
|
|
||||||
|
contract C { |
||||||
|
address public calledContract; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
calledContract = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; |
||||||
|
} |
||||||
|
|
||||||
|
function foo() public returns (uint256) { |
||||||
|
assembly { |
||||||
|
mstore(0x80, 0x4c63e562) |
||||||
|
mstore(0xa0, 1) |
||||||
|
|
||||||
|
let addr := sload(calledContract.slot) |
||||||
|
let beforegas := gas() |
||||||
|
let success := callcode(gas(), addr, 0, 0x9c, 0x24, 0, 0) |
||||||
|
let aftergas := gas() |
||||||
|
mstore(0x80, sub(beforegas, aftergas)) |
||||||
|
return(0x80, 0x20) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
contract TestCheatGas { |
||||||
|
uint256 spent = 123456; |
||||||
|
C foo; |
||||||
|
|
||||||
|
constructor() { |
||||||
|
foo = new C(); |
||||||
|
} |
||||||
|
|
||||||
|
function bar() public { |
||||||
|
spent = foo.foo(); |
||||||
|
} |
||||||
|
|
||||||
|
function echidna_gas_zero() public returns (bool){ |
||||||
|
// 0x14 as measured from opcodes, but let's leave some leeway in case solc changes |
||||||
|
// GAS PUSH1 0x0 DUP1 PUSH1 0x24 PUSH1 0x9C PUSH1 0x0 DUP7 GAS CALLCODE GAS |
||||||
|
return spent > 0x20; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue