Skip to content

Commit 6ee60aa

Browse files
author
Leo Alt
committed
Fix false positive on external calls from constructors
1 parent 23b16a1 commit 6ee60aa

File tree

5 files changed

+22
-2
lines changed

5 files changed

+22
-2
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Compiler Features:
77

88

99
Bugfixes:
10+
* SMTChecker: Fix false positive in external calls from constructors.
1011

1112

1213

libsolidity/formal/CHC.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,9 @@ void CHC::externalFunctionCall(FunctionCall const& _funCall)
756756
for (auto var: function->returnParameters())
757757
m_context.variable(*var)->increaseIndex();
758758

759+
if (!m_currentFunction || m_currentFunction->isConstructor())
760+
return;
761+
759762
auto preCallState = vector<smtutil::Expression>{state().state()} + currentStateVariables();
760763
bool usesStaticCall = kind == FunctionType::Kind::BareStaticCall ||
761764
function->stateMutability() == StateMutability::Pure ||
@@ -787,6 +790,7 @@ void CHC::externalFunctionCall(FunctionCall const& _funCall)
787790
m_context.addAssertion(nondetCall);
788791
solAssert(m_errorDest, "");
789792
connectBlocks(m_currentBlock, predicate(*m_errorDest), errorFlag().currentValue() > 0);
793+
790794
// To capture the possibility of a reentrant call, we record in the call graph that the current function
791795
// can call any of the external methods of the current contract.
792796
if (m_currentFunction)

test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_1.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ contract C {
1616
// SMTEngine: all
1717
// ----
1818
// Warning 6328: (69-85): CHC: Assertion violation happens here.\nCounterexample:\n\n_x = 100\n = 0\n\nTransaction trace:\nState.constructor()\nState.f(100)
19-
// Warning 6328: (177-191): CHC: Assertion violation happens here.\nCounterexample:\ns = 0, z = 3\n\nTransaction trace:\nC.constructor()\nState: s = 0, z = 3\nC.f()
19+
// Warning 6328: (177-191): CHC: Assertion violation happens here.\nCounterexample:\ns = 0, z = 0\n\nTransaction trace:\nC.constructor()\nState: s = 0, z = 0\nC.f()

test/libsolidity/smtCheckerTests/external_calls/external_call_from_constructor_3.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ contract C {
2020
// SMTEngine: all
2121
// ----
2222
// Warning 6328: (69-85): CHC: Assertion violation happens here.\nCounterexample:\n\n_x = 100\n = 0\n\nTransaction trace:\nState.constructor()\nState.f(100)
23-
// Warning 6328: (203-217): CHC: Assertion violation happens here.\nCounterexample:\ns = 0, z = 0\n\nTransaction trace:\nC.constructor()\nState: s = 0, z = 0\nC.f()
23+
// Warning 6328: (203-217): CHC: Assertion violation happens here.\nCounterexample:\ns = 0, z = 3\n\nTransaction trace:\nC.constructor()\nState: s = 0, z = 3\nC.f()
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface D {
2+
function ext(C c) external returns (uint);
3+
}
4+
5+
contract C {
6+
uint x;
7+
function s(uint _x) public { x = _x; }
8+
constructor(D d) {
9+
uint a = d.ext(this);
10+
assert(x == 0); // should hold because there's no reentrancy from the constructor
11+
assert(a == 2); // should fail
12+
}
13+
}
14+
// ----
15+
// Warning 6328: (253-267): CHC: Assertion violation happens here.\nCounterexample:\nx = 0\nd = 0\na = 3\n\nTransaction trace:\nC.constructor(0)

0 commit comments

Comments
 (0)