Skip to content

Conversation

@matheusaaguiar
Copy link
Collaborator

@matheusaaguiar matheusaaguiar commented Nov 19, 2025

transfer is deprecated and will be removed in the next breaking release.
depends on #16174.

@matheusaaguiar matheusaaguiar force-pushed the update-deprecated-smt-tests branch from 50bc5f0 to 3b6fdc2 Compare November 19, 2025 16:37
Copy link
Collaborator

@cameel cameel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a look from @blishko.

Looks like some of the balance tests actually do depend on properties of transfer() and SMTChecker is not able to prove the same things with call(). We'd need something else to replace it.

Also, some of the CLI tests for specific targets have empty output for those targets, which means we're not actually testing that the things works.

I'm not sure how much of it is actually worth fixing. We plan to deprecate BMC in 0.9 anyway. Some of these apply to CMC though.

Comment on lines -92 to +95
--> input.sol:13:3:
a.call{value: x}("") -- untrusted external call
--> input.sol:14:3:
Copy link
Collaborator

@cameel cameel Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... so transfer() was not treated as an untrusted external call but call() is? Perhaps SMTChecker should treat call() with empty payload and a gas limit specially?

Comment on lines 49 to +51
Note: Callstack:
Note:

Warning: BMC: Insufficient funds happens here.
--> input.sol:10:3:
|
10 | a.transfer(x);
| ^^^^^^^^^^^^^
Note: Counterexample:
a = 0
x = 0

Note: Callstack:
Note:
Note:
Note that external function calls are not inlined, even if the source code of the function is available. This is due to the possibility that the actual called contract has the same ABI but implements the function differently.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently SMTChecker can figure this out with transfer() but not with call()?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like SMTChecker can no longer detect insufficient balance when we use call(). Since this is the point of the test, we should replace it with something that actually does trigger this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, we could also keep transfer() in this particular test. There's a chance we'll drop BMC before we drop transfer() and send() anyway.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, but we're not dropping CHC, so this one needs an actual fix.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like SMTChecker fails to detect the constant condition here (though it was like this already before this PR).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another case where the target is not actually reported.

Comment on lines -62 to 9
"component": "general",
"errorCode": "9207",
"formattedMessage": "Warning: 'transfer' is deprecated and scheduled for removal in the next breaking version (0.9). Use 'call{value: <amount>}(\"\")' instead.
--> A:11:7:
|
11 | \t\t\t\t\t\ta.transfer(x);
| \t\t\t\t\t\t^^^^^^^^^^

",
"message": "'transfer' is deprecated and scheduled for removal in the next breaking version (0.9). Use 'call{value: <amount>}(\"\")' instead.",
"severity": "warning",
"sourceLocation": {
"end": 234,
"file": "A",
"start": 224
},
"type": "Warning"
},
{
"component": "general",
"errorCode": "4661",
"formattedMessage": "Warning: BMC: Assertion violation happens here.
--> A:12:7:
|
12 | \t\t\t\t\t\tassert(x > 0);
| \t\t\t\t\t\t^^^^^^^^^^^^^
Note: Counterexample:
a = 0
x = 0

Note: Callstack:
Note:

",
"message": "BMC: Assertion violation happens here.",
"secondarySourceLocations": [
{
"message": "Counterexample:
a = 0
x = 0
"
},
{
"message": "Callstack:"
},
{
"message": ""
}
],
"severity": "warning",
"sourceLocation": {
"end": 258,
"file": "A",
"start": 245
},
"type": "Warning"
}
],
"sources": {
"A": {
"id": 0
"formattedMessage": "parse error at line 7, column 458: syntax error while parsing object - unexpected string literal; expected '}'",
"message": "parse error at line 7, column 458: syntax error while parsing object - unexpected string literal; expected '}'",
"severity": "error",
"type": "JSONError"
}
Copy link
Collaborator

@cameel cameel Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the expected output here. I think you broke it by not escaping the quotes in JSON.

Comment on lines 5 to -16
function shouldHold() public {
uint tempAmount = address(this).balance;
recipient.transfer(tempAmount);
recipient.transfer(amount);
(bool success, ) = recipient.call{value: tempAmount}("");
require(success);
(success, ) = recipient.call{value: amount}("");
require(success);
}
}
// ====
// SMTEngine: chc
// ----
// Warning 9207: (133-151): 'transfer' is deprecated and scheduled for removal in the next breaking version (0.9). Use 'call{value: <amount>}("")' instead.
// Warning 9207: (167-185): 'transfer' is deprecated and scheduled for removal in the next breaking version (0.9). Use 'call{value: <amount>}("")' instead.
// Info 1391: CHC: 2 verification condition(s) proved safe! Enable the model checker option "show proved safe" to see all of them.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test no longer is proved safe with call().

@blishko
Copy link
Collaborator

blishko commented Nov 26, 2025

How important is this right now?
I guess we need to implement handling of call with value the same way we now handle transfer?

@cameel
Copy link
Collaborator

cameel commented Nov 26, 2025

How important is this right now?

We will have to deal with it in some way eventually, because send()/transfer() are going to be removed and these tests will start failing, but it will only happen in 0.9, so it's not urgent at all. It only came up now because in #16174 we're adding deprecation warnings and it seemed straightforward to update these tests. Looks like it's not that straightforward after all :)

I guess we need to implement handling of call with value the same way we now handle transfer?

Another option is also to wait for the PAY opcode and replace it with that. If it gets into Glamsterdam it could even happen before 0.9 ships :)

Maybe just leaving it as is and going back to it when the bultins are actually removed is the best course of action here. But I was just wondering whether you'd still plan to address this properly or if we should rather assume that this will just become irrelevant at some point due to changing plans (deprecations, move to Core Solidity, new tool for verification at Yul level, etc.).

@blishko
Copy link
Collaborator

blishko commented Nov 27, 2025

I believe it will eventually become irrelevant, but we might need to fix it properly before that.
I can do it before 0.9, but I would prefer to do all the necessary things in one batch.

So I would wait with this a bit to see if the situation is clearer in the future (e.g., the PAY opcode).

@cameel
Copy link
Collaborator

cameel commented Nov 27, 2025

ok. In that case in this PR we'll just replace the simple cases that cause no issues and leave the ones that do (e.g. the ones that are related to balance or specifically test transfer()) unchanged, to be dealt with later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

has dependencies The PR depends on other PRs that must be merged first smt testing 🔨

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants