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.prank
before 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!