Make arbitrary delegatecalls to an implementation contract.
Supplements vm.prank.
$ forge install adhusson/delegate-prank
You already know how to make an address c call dest.fn(args):
vm.prank(c);
dest.fn(args);Now you can make c delegatecall dest.fn(args):
delegatePrank(c,address(dest),abi.encodeCall(dest.fn,(args)));It works by swapping the bytecode of the pranked address with a delegator contract.
Cool things:
- The bytecode is swapped back on the fly, so you can never tell your bytecode got changed. This means reentrancy works.
- You can still
vm.prankbefore usingdelegatePrank
import {DelegatePrank} from "delegate-prank/DelegatePrank.sol";
contract MyTest is Test, DelegatePrank {
address multisig;
Spell spell;
...
function test_one() public {
bytes memory cd = abi.encodeCall(spell.execute,());
delegatePrank(multisig,address(spell),cd);
}
}Thanks to @ckksec for the idea of restoring the bytecode automatically!