Skip to content

Commit e3d2677

Browse files
committed
Handle constructor expectRevert
1 parent 6182d31 commit e3d2677

File tree

2 files changed

+151
-13
lines changed

2 files changed

+151
-13
lines changed

crates/cheatcodes/src/fs.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -371,19 +371,22 @@ fn deploy_code(
371371
revm::primitives::CreateScheme::Create
372372
};
373373

374-
let address = executor
375-
.exec_create(
376-
CreateInputs {
377-
caller: ccx.caller,
378-
scheme,
379-
value: value.unwrap_or(U256::ZERO),
380-
init_code: bytecode.into(),
381-
gas_limit: ccx.gas_limit,
382-
},
383-
ccx,
384-
)?
385-
.address
386-
.ok_or_else(|| fmt_err!("contract creation failed"))?;
374+
let outcome = executor.exec_create(
375+
CreateInputs {
376+
caller: ccx.caller,
377+
scheme,
378+
value: value.unwrap_or(U256::ZERO),
379+
init_code: bytecode.into(),
380+
gas_limit: ccx.gas_limit,
381+
},
382+
ccx,
383+
)?;
384+
385+
if !outcome.result.result.is_ok() {
386+
return Err(crate::Error::from(outcome.result.output))
387+
}
388+
389+
let address = outcome.address.ok_or_else(|| fmt_err!("contract creation failed"))?;
387390

388391
Ok(address.abi_encode())
389392
}

crates/forge/tests/cli/test_optimizer.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,3 +1165,138 @@ Compiling 1 files with [..]
11651165
11661166
"#]]);
11671167
});
1168+
1169+
// Counter contract with constructor reverts and emitted events.
1170+
forgetest_init!(preprocess_contract_with_require_and_emit, |prj, cmd| {
1171+
prj.wipe_contracts();
1172+
prj.update_config(|config| {
1173+
config.dynamic_test_linking = true;
1174+
});
1175+
1176+
prj.add_source(
1177+
"Counter.sol",
1178+
r#"
1179+
contract Counter {
1180+
event CounterCreated(uint256 number);
1181+
uint256 public number;
1182+
1183+
constructor(uint256 no) {
1184+
require(no != 1, "ctor revert");
1185+
emit CounterCreated(10);
1186+
}
1187+
}
1188+
"#,
1189+
)
1190+
.unwrap();
1191+
1192+
prj.add_test(
1193+
"Counter.t.sol",
1194+
r#"
1195+
import {Test} from "forge-std/Test.sol";
1196+
import {Counter} from "../src/Counter.sol";
1197+
1198+
contract CounterTest is Test {
1199+
function test_assert_constructor_revert() public {
1200+
vm.expectRevert("ctor revert");
1201+
new Counter(1);
1202+
}
1203+
1204+
function test_assert_constructor_emit() public {
1205+
vm.expectEmit(true, true, true, true);
1206+
emit Counter.CounterCreated(10);
1207+
1208+
new Counter(11);
1209+
}
1210+
}
1211+
"#,
1212+
)
1213+
.unwrap();
1214+
// All 20 files are compiled on first run.
1215+
cmd.args(["test"]).with_no_redact().assert_success().stdout_eq(str![[r#"
1216+
...
1217+
Compiling 20 files with [..]
1218+
...
1219+
1220+
"#]]);
1221+
1222+
// Change Counter implementation to revert with different message.
1223+
prj.add_source(
1224+
"Counter.sol",
1225+
r#"
1226+
contract Counter {
1227+
event CounterCreated(uint256 number);
1228+
uint256 public number;
1229+
1230+
constructor(uint256 no) {
1231+
require(no != 1, "ctor revert update");
1232+
emit CounterCreated(10);
1233+
}
1234+
}
1235+
"#,
1236+
)
1237+
.unwrap();
1238+
// Assert that only 1 file is compiled (Counter source contract) and revert test fails.
1239+
cmd.with_no_redact().assert_failure().stdout_eq(str![[r#"
1240+
...
1241+
Compiling 1 files with [..]
1242+
...
1243+
[PASS] test_assert_constructor_emit() (gas: [..])
1244+
[FAIL: Error != expected error: ctor revert update != ctor revert] test_assert_constructor_revert() (gas: [..])
1245+
...
1246+
1247+
"#]]);
1248+
1249+
// Change Counter implementation and don't revert.
1250+
prj.add_source(
1251+
"Counter.sol",
1252+
r#"
1253+
contract Counter {
1254+
event CounterCreated(uint256 number);
1255+
uint256 public number;
1256+
1257+
constructor(uint256 no) {
1258+
require(no != 0, "ctor revert");
1259+
emit CounterCreated(10);
1260+
}
1261+
}
1262+
"#,
1263+
)
1264+
.unwrap();
1265+
// Assert that only 1 file is compiled (Counter source contract) and revert test fails.
1266+
cmd.with_no_redact().assert_failure().stdout_eq(str![[r#"
1267+
...
1268+
Compiling 1 files with [..]
1269+
...
1270+
[PASS] test_assert_constructor_emit() (gas: [..])
1271+
[FAIL: next call did not revert as expected] test_assert_constructor_revert() (gas: [..])
1272+
...
1273+
1274+
"#]]);
1275+
1276+
// Change Counter implementation to emit different event.
1277+
prj.add_source(
1278+
"Counter.sol",
1279+
r#"
1280+
contract Counter {
1281+
event CounterCreated(uint256 number);
1282+
uint256 public number;
1283+
1284+
constructor(uint256 no) {
1285+
require(no != 0, "ctor revert");
1286+
emit CounterCreated(100);
1287+
}
1288+
}
1289+
"#,
1290+
)
1291+
.unwrap();
1292+
// Assert that only 1 file is compiled (Counter source contract) and emit test fails.
1293+
cmd.with_no_redact().assert_failure().stdout_eq(str![[r#"
1294+
...
1295+
Compiling 1 files with [..]
1296+
...
1297+
[FAIL: expected an emit, but no logs were emitted afterwards. you might have mismatched events or not enough events were emitted] test_assert_constructor_emit() (gas: [..])
1298+
[FAIL: next call did not revert as expected] test_assert_constructor_revert() (gas: [..])
1299+
...
1300+
1301+
"#]]);
1302+
});

0 commit comments

Comments
 (0)