Disallow comparison operators on contracts

This commit is contained in:
Marenz 2022-01-20 17:05:52 +01:00
parent 777385f5d2
commit f426b5988e
12 changed files with 45 additions and 18 deletions

View File

@ -2,8 +2,9 @@
Breaking changes:
* Disallow ``.pop()`` on arrays containing nested mappings.
* Disallow ``delete`` on types that contain nested mappings.
* Disallow ``codecopy`` and ``codesize`` in ``pure`` functions.
* Disallow ``delete`` on types that contain nested mappings.
* Disallow all comparison operators on contract types.
* Inline Assembly: Consider functions, function parameters and return variables for shadowing checks.
* Commandline Interface: Remapping targets are not automatically added to allowed paths.
* Commandline Interface: Assembler mode no longer enables all outputs by default.

View File

@ -927,6 +927,11 @@ public:
BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
/// Contracts can only be explicitly converted to address types and base contracts.
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
/// Contracts do not support any comparison operators
TypeResult binaryOperatorResult(Token, Type const*) const override
{
return TypeResult::err("No arithmetic or comparison operations are allowed on contract types. Consider converting to \"address\".");
}
TypeResult unaryOperatorResult(Token _operator) const override;
std::string richIdentifier() const override;
bool operator==(Type const& _other) const override;

View File

@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(value_types)
if (d != 4) return 4;
if (x != "abc") return 5;
if (e != true) return 6;
if (g != this) return 7;
if (address(g) != address(this)) return 7;
return 20;
}
}

View File

@ -6,7 +6,7 @@ contract A {
function different_salt() public returns (bool) {
B x = new B{salt: "abc"}();
B y = new B{salt: "abcef"}();
return x != y;
return address(x) != address(y);
}
function same_salt() public returns (bool) {
B x = new B{salt: "xyz"}();

View File

@ -5,11 +5,11 @@ contract C {
function f() public view {
D e = this.d();
assert(e == d); // should hold
assert(address(e) == address(d)); // should hold
assert(address(e) == address(this)); // should fail
}
}
// ====
// SMTEngine: all
// ----
// Warning 6328: (123-158): CHC: Assertion violation happens here.\nCounterexample:\nd = 0\ne = 0\n\nTransaction trace:\nC.constructor()\nState: d = 0\nC.f()
// Warning 6328: (141-176): CHC: Assertion violation happens here.\nCounterexample:\nd = 0\ne = 0\n\nTransaction trace:\nC.constructor()\nState: d = 0\nC.f()

View File

@ -11,7 +11,7 @@ contract C {
function test() public view {
(D d, function () external returns (uint) f) = this.s();
assert(d == s.d); // should hold
assert(address(d) == address(s.d)); // should hold
assert(address(d) == address(this)); // should fail
}
}
@ -19,4 +19,4 @@ contract C {
// SMTEngine: all
// ----
// Warning 2072: (146-183): Unused local variable.
// Warning 6328: (234-269): CHC: Assertion violation happens here.\nCounterexample:\ns = {d: 0, f: 0}\nd = 0\nf = 0\n\nTransaction trace:\nC.constructor()\nState: s = {d: 0, f: 0}\nC.test()
// Warning 6328: (252-287): CHC: Assertion violation happens here.\nCounterexample:\ns = {d: 0, f: 0}\nd = 0\nf = 0\n\nTransaction trace:\nC.constructor()\nState: s = {d: 0, f: 0}\nC.test()

View File

@ -1,11 +1,11 @@
contract C
{
function f(C c, C d) public pure {
assert(c == d);
assert(address(c) == address(d));
}
}
// ====
// SMTEngine: all
// SMTIgnoreCex: yes
// ----
// Warning 6328: (51-65): CHC: Assertion violation happens here.
// Warning 6328: (51-83): CHC: Assertion violation happens here.

View File

@ -6,11 +6,11 @@ contract D
contract C
{
function f(D c, D d) public pure {
assert(c == d);
assert(address(c) == address(d));
}
}
// ====
// SMTEngine: all
// SMTIgnoreCex: yes
// ----
// Warning 6328: (76-90): CHC: Assertion violation happens here.
// Warning 6328: (76-108): CHC: Assertion violation happens here.

View File

@ -1,9 +1,9 @@
contract C
{
function f(C c, C d, C e) public pure {
require(c == d);
require(d == e);
assert(c == e);
require(address(c) == address(d));
require(address(d) == address(e));
assert(address(c) == address(e));
}
}
// ====

View File

@ -3,7 +3,7 @@ contract C
function f(C c, C d) public pure {
assert(address(c) == address(c));
address a = address(c);
require(c == d);
require(address(c) == address(d));
assert(a == address(d));
}
}

View File

@ -20,8 +20,8 @@ contract C {
}
// ----
// TypeError 2271: (144-157): Operator != not compatible with types type(contract super C) and contract C
// TypeError 2271: (167-180): Operator != not compatible with types contract C and type(contract super C)
// TypeError 2271: (167-180): Operator != not compatible with types contract C and type(contract super C). No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".
// TypeError 2271: (254-264): Operator != not compatible with types type(contract super C) and contract C
// TypeError 2271: (274-284): Operator != not compatible with types contract C and type(contract super C)
// TypeError 2271: (274-284): Operator != not compatible with types contract C and type(contract super C). No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".
// TypeError 2271: (349-359): Operator != not compatible with types type(contract super C) and contract D
// TypeError 2271: (369-379): Operator != not compatible with types contract D and type(contract super C)
// TypeError 2271: (369-379): Operator != not compatible with types contract D and type(contract super C). No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".

View File

@ -0,0 +1,21 @@
contract C {
function f(string calldata data) external pure {
C c;
assert(this == this);
assert(this == c);
assert(this != c);
assert(this >= c);
assert(this <= c);
assert(this < c);
assert(this > c);
}
}
// ----
// TypeError 2271: (79-91): Operator == not compatible with types contract C and contract C. No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".
// TypeError 2271: (104-113): Operator == not compatible with types contract C and contract C. No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".
// TypeError 2271: (125-134): Operator != not compatible with types contract C and contract C. No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".
// TypeError 2271: (146-155): Operator >= not compatible with types contract C and contract C. No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".
// TypeError 2271: (167-176): Operator <= not compatible with types contract C and contract C. No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".
// TypeError 2271: (188-196): Operator < not compatible with types contract C and contract C. No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".
// TypeError 2271: (208-216): Operator > not compatible with types contract C and contract C. No arithmetic or comparison operations are allowed on contract types. Consider converting to "address".