diff --git a/testdata/cheats/Cheats.sol b/testdata/cheats/Cheats.sol index 0fc562a77c95e..ec1a7b73ddda2 100644 --- a/testdata/cheats/Cheats.sol +++ b/testdata/cheats/Cheats.sol @@ -99,8 +99,10 @@ interface Cheats { function expectCall(address, bytes calldata) external; // Expect a call to an address with the specified msg.value and calldata function expectCall(address, uint256, bytes calldata) external; - // Gets the code from an artifact file. Takes in the relative path to the json file + // Gets the bytecode from an artifact file. Takes in the relative path to the json file function getCode(string calldata) external returns (bytes memory); + // Gets the _deployed_ bytecode from an artifact file. Takes in the relative path to the json file + function getDeployedCode(string calldata) external returns (bytes memory); // Labels an address in call traces function label(address, string calldata) external; // If the condition is false, discard this run's fuzz inputs and generate new ones diff --git a/testdata/cheats/GetDeployedCode.t.sol b/testdata/cheats/GetDeployedCode.t.sol new file mode 100644 index 0000000000000..eebd75cd5e84a --- /dev/null +++ b/testdata/cheats/GetDeployedCode.t.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity >=0.8.0; + +import "ds-test/test.sol"; +import "./Cheats.sol"; + +contract GetDeployedCodeTest is DSTest { + Cheats constant vm = Cheats(HEVM_ADDRESS); + + address public constant overrideAddress = 0x0000000000000000000000000000000000000064; + + event Payload(address sender, address target, bytes data); + + function testGetCode() public { + bytes memory fullPath = vm.getDeployedCode("../testdata/fixtures/GetCode/Override.json"); + string memory expected = string( + bytes( + hex"60806040526004361061001e5760003560e01c806340e04f5e14610023575b600080fd5b610036610031366004610091565b610048565b60405190815260200160405180910390f35b60007fda9986ad4da7abb3f55b2d1f2009ab6ee50c5ad054092c04464c112acc4bc1103385858560405161007f9493929190610122565b60405180910390a15060009392505050565b6000806000604084860312156100a657600080fd5b83356001600160a01b03811681146100bd57600080fd5b9250602084013567ffffffffffffffff808211156100da57600080fd5b818601915086601f8301126100ee57600080fd5b8135818111156100fd57600080fd5b87602082850101111561010f57600080fd5b6020830194508093505050509250925092565b6001600160a01b0385811682528416602082015260606040820181905281018290526000828460808401376000608084840101526080601f19601f85011683010190509594505050505056fea26469706673582212202b0ba0fa4073d6f681bb1f99f0529e44583f2dc612a629f3ff0564eaa7257d1f64736f6c63430008110033" + ) + ); + assertEq(string(fullPath), expected, "deployed code for full path was incorrect"); + } + + // this will set the deployed bytecode of the stateless contract to the `overrideAddress` and call the function that emits an event that will be `expectEmitted` + function testCanEtchStatelessOverride() public { + bytes memory code = vm.getDeployedCode("../testdata/fixtures/GetCode/Override.json"); + vm.etch(overrideAddress, code); + assertEq( + overrideAddress.code, + hex"60806040526004361061001e5760003560e01c806340e04f5e14610023575b600080fd5b610036610031366004610091565b610048565b60405190815260200160405180910390f35b60007fda9986ad4da7abb3f55b2d1f2009ab6ee50c5ad054092c04464c112acc4bc1103385858560405161007f9493929190610122565b60405180910390a15060009392505050565b6000806000604084860312156100a657600080fd5b83356001600160a01b03811681146100bd57600080fd5b9250602084013567ffffffffffffffff808211156100da57600080fd5b818601915086601f8301126100ee57600080fd5b8135818111156100fd57600080fd5b87602082850101111561010f57600080fd5b6020830194508093505050509250925092565b6001600160a01b0385811682528416602082015260606040820181905281018290526000828460808401376000608084840101526080601f19601f85011683010190509594505050505056fea26469706673582212202b0ba0fa4073d6f681bb1f99f0529e44583f2dc612a629f3ff0564eaa7257d1f64736f6c63430008110033" + ); + + Override over = Override(overrideAddress); + + vm.expectEmit(true, false, false, true); + over.emitPayload(address(0), "hello"); + emit Payload(address(this), address(0), "hello"); + } +} + +interface Override { + function emitPayload(address target, bytes calldata message) external payable returns (uint256); +} diff --git a/testdata/fixtures/GetCode/Override.json b/testdata/fixtures/GetCode/Override.json new file mode 100644 index 0000000000000..e91dd321f961f --- /dev/null +++ b/testdata/fixtures/GetCode/Override.json @@ -0,0 +1,12 @@ +{ + "bytecode": { + "object": "0x608060405234801561001057600080fd5b506101a4806100206000396000f3fe60806040526004361061001e5760003560e01c806340e04f5e14610023575b600080fd5b610036610031366004610091565b610048565b60405190815260200160405180910390f35b60007fda9986ad4da7abb3f55b2d1f2009ab6ee50c5ad054092c04464c112acc4bc1103385858560405161007f9493929190610122565b60405180910390a15060009392505050565b6000806000604084860312156100a657600080fd5b83356001600160a01b03811681146100bd57600080fd5b9250602084013567ffffffffffffffff808211156100da57600080fd5b818601915086601f8301126100ee57600080fd5b8135818111156100fd57600080fd5b87602082850101111561010f57600080fd5b6020830194508093505050509250925092565b6001600160a01b0385811682528416602082015260606040820181905281018290526000828460808401376000608084840101526080601f19601f85011683010190509594505050505056fea26469706673582212202b0ba0fa4073d6f681bb1f99f0529e44583f2dc612a629f3ff0564eaa7257d1f64736f6c63430008110033", + "sourceMap": "65:263:0:-:0;;;;;;;;;;;;;;;;;;;", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x60806040526004361061001e5760003560e01c806340e04f5e14610023575b600080fd5b610036610031366004610091565b610048565b60405190815260200160405180910390f35b60007fda9986ad4da7abb3f55b2d1f2009ab6ee50c5ad054092c04464c112acc4bc1103385858560405161007f9493929190610122565b60405180910390a15060009392505050565b6000806000604084860312156100a657600080fd5b83356001600160a01b03811681146100bd57600080fd5b9250602084013567ffffffffffffffff808211156100da57600080fd5b818601915086601f8301126100ee57600080fd5b8135818111156100fd57600080fd5b87602082850101111561010f57600080fd5b6020830194508093505050509250925092565b6001600160a01b0385811682528416602082015260606040820181905281018290526000828460808401376000608084840101526080601f19601f85011683010190509594505050505056fea26469706673582212202b0ba0fa4073d6f681bb1f99f0529e44583f2dc612a629f3ff0564eaa7257d1f64736f6c63430008110033", + "sourceMap": "65:263:0:-:0;;;;;;;;;;;;;;;;;;;;;154:172;;;;;;:::i;:::-;;:::i;:::-;;;930:25:1;;;918:2;903:18;154:172:0;;;;;;;;241:7;265:36;273:10;285:6;293:7;;265:36;;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;318:1:0;154:172;;;;;:::o;14:765:1:-;93:6;101;109;162:2;150:9;141:7;137:23;133:32;130:52;;;178:1;175;168:12;130:52;204:23;;-1:-1:-1;;;;;256:31:1;;246:42;;236:70;;302:1;299;292:12;236:70;325:5;-1:-1:-1;381:2:1;366:18;;353:32;404:18;434:14;;;431:34;;;461:1;458;451:12;431:34;499:6;488:9;484:22;474:32;;544:7;537:4;533:2;529:13;525:27;515:55;;566:1;563;556:12;515:55;606:2;593:16;632:2;624:6;621:14;618:34;;;648:1;645;638:12;618:34;693:7;688:2;679:6;675:2;671:15;667:24;664:37;661:57;;;714:1;711;704:12;661:57;745:2;741;737:11;727:21;;767:6;757:16;;;;;14:765;;;;;:::o;966:589::-;-1:-1:-1;;;;;1217:15:1;;;1199:34;;1269:15;;1264:2;1249:18;;1242:43;1321:2;1316;1301:18;;1294:30;;;1340:18;;1333:34;;;1142:4;1360:6;1410;1404:3;1389:19;;1376:49;1475:1;1469:3;1460:6;1449:9;1445:22;1441:32;1434:43;1545:3;1538:2;1534:7;1529:2;1521:6;1517:15;1513:29;1502:9;1498:45;1494:55;1486:63;;966:589;;;;;;;:::o", + "linkReferences": {} + } +} \ No newline at end of file diff --git a/testdata/fixtures/GetCode/Override.sol b/testdata/fixtures/GetCode/Override.sol new file mode 100644 index 0000000000000..1c3875650c17a --- /dev/null +++ b/testdata/fixtures/GetCode/Override.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Override { + event Payload(address sender, address target, bytes data); + + function emitPayload(address target, bytes calldata message) external payable returns (uint256) { + emit Payload(msg.sender, target, message); + return 0; + } +}