// File: src/ExploitFactory.sol



// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

contract ExploitFactory {

    function deployAndExecute(
        bytes32 salt,
        bytes calldata creationCode,
        bytes calldata callData
    ) public payable returns (address, bytes memory) {
        address addr = _deploy(salt, creationCode);

        ( bool success, bytes memory returnData ) = addr.call(callData);

        require(success, "ExploitFactory/execution-failed");

        return (addr, returnData);
    }

    function _deploy(bytes32 salt, bytes memory creationCode) internal returns (address addr) {
        require(creationCode.length != 0, "ExploitFactory/empty-code");

        assembly {
            addr := create2(callvalue(), add(creationCode, 0x20), mload(creationCode), salt)
        }

        require(addr != address(0), "ExploitFactory/failed-deployment");
    }

    function computeContractAddress(bytes32 salt, bytes32 codeHash) public view returns (address) {
        return address(uint160(uint(keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            salt,
            codeHash
        )))));
    }

}