Skip to content

Commit 52ad574

Browse files
authored
Merge pull request #33 from axieinfinity/feature/onchain-executor
feat: add OnchainExecutor contract to debug and broadcast raw tx
2 parents d524af3 + 27143b5 commit 52ad574

File tree

7 files changed

+122
-55
lines changed

7 files changed

+122
-55
lines changed

.broadcast.env.example

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Fork block number to debug
2+
BLOCK=0x0
3+
# Caller
4+
FROM=0x0000000000000000000000000000000000000000
5+
# Callee
6+
TO=0x0000000000000000000000000000000000000000
7+
# Sent Value
8+
VALUE=0
9+
# Gas Amount
10+
GAS=0
11+
# Call Data
12+
CALLDATA=0x0

.debug.env.example

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ FROM=0x0000000000000000000000000000000000000000
55
# Callee
66
TO=0x0000000000000000000000000000000000000000
77
# Sent Value
8-
VALUE=0x27cdb0997a65b2de99
8+
VALUE=0
9+
# Gas Amount
10+
GAS=0
911
# Call Data
1012
CALLDATA=0x0

broadcast.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Source (or "dot") the .env file to load environment variables
2+
if [ -f .env ]; then
3+
source .broadcast.env
4+
else
5+
echo "Error: .broadcast.env file not found."
6+
fi
7+
8+
verify_arg=""
9+
extra_argument=""
10+
11+
for arg in "$@"; do
12+
case $arg in
13+
--trezor)
14+
extra_argument+=trezor@
15+
;;
16+
*) ;;
17+
esac
18+
done
19+
20+
# Remove the @ character from the end of extra_argument
21+
extra_argument="${extra_argument%%@}"
22+
23+
echo Broadcast Tx...
24+
echo From: ${FROM}
25+
echo To: ${TO}
26+
echo Value: ${VALUE}
27+
echo GasAmount: ${GAS}
28+
echo Calldata:
29+
cast pretty-calldata ${CALLDATA}
30+
calldata=$(cast calldata 'broadcast(address,address,uint256,uint256,bytes)' ${FROM} ${TO} ${GAS} ${VALUE} ${CALLDATA})
31+
forge script ${verify_arg} ${@} -g 200 OnchainExecutor --sig 'run(bytes,string)' ${calldata} "${extra_argument}"

debug.sh

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,12 @@ fi
77

88
verify_arg=""
99
extra_argument=""
10-
op_command="op run --env-file="./.env" --"
1110

1211
for arg in "$@"; do
1312
case $arg in
1413
--trezor)
15-
op_command=""
1614
extra_argument+=trezor@
1715
;;
18-
--broadcast)
19-
op_command="op run --env-file="./.env" --"
20-
;;
21-
--log)
22-
set -- "${@/#--log/}"
23-
extra_argument+=log@
24-
;;
2516
*) ;;
2617
esac
2718
done
@@ -33,7 +24,8 @@ echo Debug Tx...
3324
echo From: ${FROM}
3425
echo To: ${TO}
3526
echo Value: ${VALUE}
27+
echo GasAmount: ${GAS}
3628
echo Calldata:
3729
cast pretty-calldata ${CALLDATA}
38-
calldata=$(cast calldata 'trace(uint256,address,address,uint256,bytes)' ${BLOCK} ${FROM} ${TO} ${VALUE} ${CALLDATA})
39-
${op_command} forge script ${verify_arg} --legacy ${@} OnchainDebugger --sig 'run(bytes,string)' ${calldata} "${extra_argument}"
30+
calldata=$(cast calldata 'trace(uint256,address,address,uint256,uint256,bytes)' ${BLOCK} ${FROM} ${TO} ${GAS} ${VALUE} ${CALLDATA})
31+
forge script ${verify_arg} --legacy ${@} OnchainExecutor --sig 'run(bytes,string)' ${calldata} "${extra_argument}"

script/BaseMigration.s.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { LibString } from "../lib/solady/src/utils/LibString.sol";
1010
import { console, LibSharedAddress, StdStyle, IScriptExtended, ScriptExtended } from "./extensions/ScriptExtended.s.sol";
1111
import { IArtifactFactory, ArtifactFactory } from "./ArtifactFactory.sol";
12-
import { OnchainDebugger } from "./OnchainDebugger.s.sol"; // cheat to load artifact to parent `out` directory
12+
import { OnchainExecutor } from "./OnchainExecutor.s.sol"; // cheat to load artifact to parent `out` directory
1313
import { IMigrationScript } from "./interfaces/IMigrationScript.sol";
1414
import { LibProxy } from "./libraries/LibProxy.sol";
1515
import { DefaultContract } from "./utils/DefaultContract.sol";
@@ -272,4 +272,4 @@ abstract contract BaseMigration is ScriptExtended {
272272
function _setDependencyDeployScript(TContract contractType, address deployScript) internal virtual {
273273
_deployScript[contractType] = IMigrationScript(deployScript);
274274
}
275-
}
275+
}

script/OnchainDebugger.s.sol

Lines changed: 0 additions & 41 deletions
This file was deleted.

script/OnchainExecutor.s.sol

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.19;
3+
4+
import { StdStyle } from "../lib/forge-std/src/StdStyle.sol";
5+
import { console2 as console } from "../lib/forge-std/src/console2.sol";
6+
import { ScriptExtended } from "./extensions/ScriptExtended.s.sol";
7+
import { BaseGeneralConfig } from "./BaseGeneralConfig.sol";
8+
import { LibErrorHandler } from "../lib/contract-libs/src/LibErrorHandler.sol";
9+
10+
contract OnchainExecutor is ScriptExtended {
11+
using LibErrorHandler for bool;
12+
13+
modifier rollFork(uint256 forkBlock) {
14+
if (forkBlock != 0) {
15+
vm.rollFork(forkBlock);
16+
console.log("OnchainExecutor: Rolling to fork block number:", forkBlock);
17+
}
18+
_;
19+
}
20+
21+
function _configByteCode() internal virtual override returns (bytes memory) {
22+
return abi.encodePacked(type(BaseGeneralConfig).creationCode, abi.encode("", "deployments/"));
23+
}
24+
25+
function trace(uint256 forkBlock, address from, address to, uint256 gas, uint256 value, bytes calldata callData)
26+
public
27+
rollFork(forkBlock)
28+
{
29+
vm.prank(from);
30+
_sendRawTransaction(to, gas, value, callData);
31+
}
32+
33+
function broadcast(address from, address to, uint256 gas, uint256 value, bytes calldata callData) public {
34+
vm.broadcast(from);
35+
_sendRawTransaction(to, gas, value, callData);
36+
}
37+
38+
function _sendRawTransaction(address to, uint256 gas, uint256 value, bytes calldata callData) internal {
39+
bool success;
40+
bytes memory returnOrRevertData;
41+
42+
(success, returnOrRevertData) =
43+
gas == 0 ? to.call{ value: value }(callData) : to.call{ value: value, gas: gas }(callData);
44+
45+
if (!success) {
46+
if (returnOrRevertData.length != 0) {
47+
string[] memory commandInput = new string[](3);
48+
commandInput[0] = "cast";
49+
commandInput[1] = returnOrRevertData.length > 4 ? "4byte-decode" : "4byte";
50+
commandInput[2] = vm.toString(returnOrRevertData);
51+
bytes memory decodedError = vm.ffi(commandInput);
52+
console.log(StdStyle.red(string.concat("Decoded Error: ", string(decodedError))));
53+
} else {
54+
console.log(StdStyle.red("Evm Error!"));
55+
}
56+
} else {
57+
console.log(StdStyle.green("OnchainExecutor: Call Executed Successfully!"));
58+
}
59+
}
60+
61+
function _logDecodedError(bytes memory returnOrRevertData) internal {
62+
if (returnOrRevertData.length != 0) {
63+
string[] memory commandInput = new string[](3);
64+
commandInput[0] = "cast";
65+
commandInput[1] = returnOrRevertData.length > 4 ? "4byte-decode" : "4byte";
66+
commandInput[2] = vm.toString(returnOrRevertData);
67+
bytes memory decodedError = vm.ffi(commandInput);
68+
console.log(StdStyle.red(string.concat("Decoded Error: ", string(decodedError))));
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)