Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion contracts/BatchExecutor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ pragma solidity ^0.8.20;
///
/// receive/fallback are required so other delegated EOAs can still accept
/// plain ETH value transfers from multiSend (empty calldata must not revert).
///
/// multiSend is onlySelf: without `msg.sender == address(this)`, any third
/// party could call a delegated EOA and drain its ETH.
contract BatchExecutor {
receive() external payable {}

fallback() external payable {}

/// @notice Transfer ETH to multiple recipients.
/// @dev Must be called as the delegated EOA (to == EOA after set-code).
/// @dev Must be called as the delegated EOA (to == EOA after set-code),
/// and only by the EOA itself (msg.sender == address(this)).
function multiSend(address[] calldata recipients, uint256[] calldata amounts) external payable {
require(msg.sender == address(this), "only self");
uint256 n = recipients.length;
require(n == amounts.length, "len");
for (uint256 i = 0; i < n; ) {
Expand Down
42 changes: 23 additions & 19 deletions src/txn_plan/constructor/eip7702.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,31 +146,35 @@ pub const EIP7702_DELEGATE_DEPLOY_GAS_LIMIT: u64 = 500_000;
/// Runtime exposes `multiSend(address[],uint256[])` (selector `0xbb4c9f0b`).
/// Designed as an EIP-7702 delegation target: after set-code, call the EOA
/// with multiSend so value transfers use the EOA balance.
/// `multiSend` requires `msg.sender == address(this)` (onlySelf).
pub fn delegate_contract_bytecode() -> Vec<u8> {
// solc --bin --optimize --optimize-runs 200 contracts/BatchExecutor.sol
// Includes receive/fallback so multiSend into already-delegated EOAs succeeds.
// Includes onlySelf guard so third parties cannot drain delegated EOAs.
const HEX: &str = concat!(
"608060405234801561000f575f80fd5b506102778061001d5f395ff3fe608060",
"608060405234801561000f575f80fd5b506102b28061001d5f395ff3fe608060",
"40526004361061001e575f3560e01c8063bb4c9f0b1461002757005b36610025",
"57005b005b610025610035366004610199565b82818114610070576040516246",
"57005b005b6100256100353660046101d4565b3330146100755760405162461b",
"cd60e51b815260206004820152600960248201526837b7363c9039b2b63360b9",
"1b60448201526064015b60405180910390fd5b828181146100ab576040516246",
"1bcd60e51b81526020600482015260036024820152623632b760e91b60448201",
"526064015b60405180910390fd5b5f5b81811015610149575f86868381811061",
"008d5761008d610200565b90506020020160208101906100a29190610214565b",
"6001600160a01b03168585848181106100bd576100bd610200565b9050602002",
"01356040515f6040518083038185875af1925050503d805f8114610101576040",
"519150601f19603f3d011682016040523d82523d5f602084013e610106565b60",
"6091505b50509050806101405760405162461bcd60e51b815260040161006790",
"6020808252600490820152631cd95b9960e21b604082015260600190565b5060",
"0101610072565b505050505050565b5f8083601f840112610161575f80fd5b50",
"813567ffffffffffffffff811115610178575f80fd5b60208301915083602082",
"60051b8501011115610192575f80fd5b9250929050565b5f805f806040858703",
"12156101ac575f80fd5b843567ffffffffffffffff808211156101c3575f80fd",
"5b6101cf88838901610151565b909650945060208701359150808211156101e7",
"575f80fd5b506101f487828801610151565b95989497509550505050565b634e",
"487b7160e01b5f52603260045260245ffd5b5f60208284031215610224575f80",
"fd5b81356001600160a01b038116811461023a575f80fd5b939250505056fea2",
"646970667358221220a2fc7415ad69a852d05958c007f06988587d8766968d3b",
"7a734a15534d07c51064736f6c63430008150033",
"5260640161006c565b5f5b81811015610184575f8686838181106100c8576100",
"c861023b565b90506020020160208101906100dd919061024f565b6001600160",
"a01b03168585848181106100f8576100f861023b565b90506020020135604051",
"5f6040518083038185875af1925050503d805f811461013c576040519150601f",
"19603f3d011682016040523d82523d5f602084013e610141565b606091505b50",
"5090508061017b5760405162461bcd60e51b815260040161006c906020808252",
"600490820152631cd95b9960e21b604082015260600190565b506001016100ad",
"565b505050505050565b5f8083601f84011261019c575f80fd5b50813567ffff",
"ffffffffffff8111156101b3575f80fd5b6020830191508360208260051b8501",
"0111156101cd575f80fd5b9250929050565b5f805f80604085870312156101e7",
"575f80fd5b843567ffffffffffffffff808211156101fe575f80fd5b61020a88",
"83890161018c565b90965094506020870135915080821115610222575f80fd5b",
"5061022f8782880161018c565b95989497509550505050565b634e487b7160e0",
"1b5f52603260045260245ffd5b5f6020828403121561025f575f80fd5b813560",
"01600160a01b0381168114610275575f80fd5b939250505056fea26469706673",
"58221220361e305cccaa6daee31e970d468e4f32aa66c7ac631d269ae432b086",
"4e4be77564736f6c63430008150033",
);
hex::decode(HEX).expect("invalid BatchExecutor creation bytecode hex")
}
Loading