abi.encodeCall for declarations.

This commit is contained in:
chriseth
2021-12-29 12:26:04 +01:00
parent b28cd00aa0
commit 4c838d9cf5
8 changed files with 241 additions and 72 deletions
@@ -2,81 +2,47 @@ interface I {
function fExternal(uint256 p, string memory t) external;
}
library L {
function fExternal(uint256 p, string memory t) external {}
contract Other {
function fExternal(uint) external pure {}
function fPublic(uint) public pure {}
function fInternal(uint) internal pure {}
}
contract C {
using L for uint256;
library L {
function fExternal(uint256 p, string memory t) external {}
function fInternal(uint256 p, string memory t) internal {}
}
contract Base {
function baseFunctionExternal(uint) external pure {}
}
contract C is Base {
function f(int a) public {}
function f2(int a, string memory b) public {}
function f3(int a, int b) public {}
function f4() public {}
function fInternal(uint256 p, string memory t) internal {}
function failFunctionArgsWrongType() public returns(bytes memory) {
return abi.encodeCall(this.f, ("test"));
}
function failFunctionArgsTooMany() public returns(bytes memory) {
return abi.encodeCall(this.f, (1, 2));
}
function failFunctionArgsTooFew0() public returns(bytes memory) {
return abi.encodeCall(this.f, ());
}
function failFunctionArgsTooFew1() public returns(bytes memory) {
return abi.encodeCall(this.f);
}
function failFunctionPtrMissing() public returns(bytes memory) {
return abi.encodeCall(1, this.f);
}
function failFunctionPtrWrongType() public returns(bytes memory) {
return abi.encodeCall(abi.encodeCall, (1, 2, 3, "test"));
}
function failFunctionInternal() public returns(bytes memory) {
return abi.encodeCall(fInternal, (1, "123"));
}
function failFunctionInternalFromVariable() public returns(bytes memory) {
function(uint256, string memory) internal localFunctionPointer = fInternal;
return abi.encodeCall(localFunctionPointer, (1, "123"));
}
function failFunctionArgsArrayLiteral() public returns(bytes memory) {
return abi.encodeCall(this.f3, [1, 2]);
}
function failLibraryPointerCall() public returns (bytes memory) {
return abi.encodeCall(L.fExternal, (1, "123"));
}
function failBoundLibraryPointerCall() public returns (bytes memory) {
uint256 x = 1;
return abi.encodeCall(x.fExternal, (1, "123"));
}
function failInterfacePointerCall() public returns (bytes memory) {
return abi.encodeCall(I.fExternal, (1, "123"));
}
function successFunctionArgsIntLiteralTuple() public returns(bytes memory) {
function successFunctionArgsIntLiteralTuple() public view returns(bytes memory) {
return abi.encodeCall(this.f, (1));
}
function successFunctionArgsIntLiteral() public returns(bytes memory) {
function successFunctionArgsIntLiteral() public view returns(bytes memory) {
return abi.encodeCall(this.f, 1);
}
function successFunctionArgsLiteralTuple() public returns(bytes memory) {
function successFunctionArgsLiteralTuple() public view returns(bytes memory) {
return abi.encodeCall(this.f2, (1, "test"));
}
function successFunctionArgsEmptyTuple() public returns(bytes memory) {
function successFunctionArgsEmptyTuple() public view returns(bytes memory) {
return abi.encodeCall(this.f4, ());
}
function viaDeclaration() public pure returns (bytes memory) {
return bytes.concat(
abi.encodeCall(Other.fExternal, (1)),
abi.encodeCall(Other.fPublic, (1)),
abi.encodeCall(I.fExternal, (1, "123"))
);
}
function viaBaseDeclaration() public pure returns (bytes memory) {
return abi.encodeCall(Base.baseFunctionExternal, (1));
}
}
// ----
// TypeError 5407: (486-494): Cannot implicitly convert component at position 0 from "literal_string "test"" to "int256".
// TypeError 7788: (576-606): Expected 1 instead of 2 components for the tuple parameter.
// TypeError 7788: (687-713): Expected 1 instead of 0 components for the tuple parameter.
// TypeError 6219: (794-816): Expected two arguments: a function pointer followed by a tuple.
// TypeError 5511: (911-912): Expected first argument to be a function pointer, not "int_const 1".
// TypeError 3509: (1018-1032): Function must be "public" or "external".
// TypeError 3509: (1145-1154): Function must be "public" or "external". Did you forget to prefix "this."?
// TypeError 3509: (1350-1370): Function must be "public" or "external".
// TypeError 7515: (1469-1500): Expected a tuple with 2 components instead of a single non-tuple parameter.
// TypeError 5407: (1493-1499): Cannot implicitly convert component at position 0 from "uint8[2]" to "int256".
// TypeError 3509: (1596-1607): Function must be "public" or "external".
// TypeError 3509: (1738-1749): Function must be "public" or "external".
// TypeError 3509: (1860-1871): Function must be "public" or "external".
@@ -0,0 +1,27 @@
contract C {
function f(int a) public {}
function f3(int a, int b) public {}
function failFunctionArgsWrongType() public returns(bytes memory) {
return abi.encodeCall(this.f, ("test"));
}
function failFunctionArgsTooMany() public returns(bytes memory) {
return abi.encodeCall(this.f, (1, 2));
}
function failFunctionArgsTooFew0() public returns(bytes memory) {
return abi.encodeCall(this.f, ());
}
function failFunctionArgsTooFew1() public returns(bytes memory) {
return abi.encodeCall(this.f);
}
function failFunctionArgsArrayLiteral() public returns(bytes memory) {
return abi.encodeCall(this.f3, [1, 2]);
}
}
// ----
// TypeError 5407: (181-189): Cannot implicitly convert component at position 0 from "literal_string "test"" to "int256".
// TypeError 7788: (271-301): Expected 1 instead of 2 components for the tuple parameter.
// TypeError 7788: (382-408): Expected 1 instead of 0 components for the tuple parameter.
// TypeError 6219: (489-511): Expected two arguments: a function pointer followed by a tuple.
// TypeError 7515: (597-628): Expected a tuple with 2 components instead of a single non-tuple parameter.
// TypeError 5407: (621-627): Cannot implicitly convert component at position 0 from "uint8[2]" to "int256".
@@ -0,0 +1,78 @@
interface I {
function fExternal(uint256 p, string memory t) external;
}
contract Other {
function fExternal(uint) external pure {}
function fPublic(uint) public pure {}
function fInternal(uint) internal pure {}
}
library L {
function fExternal(uint256 p, string memory t) external {}
function fInternal(uint256 p, string memory t) internal {}
}
contract Base {
function baseFunctionInternal(uint) internal pure {}
function baseFunctionPublic(uint) public pure {}
}
function fileLevel(uint) pure {}
contract C is Base {
using L for uint256;
function fPublic(int a) public {}
function fInternal(uint256 p, string memory t) internal {}
function failFunctionPtrMissing() public returns(bytes memory) {
return abi.encodeCall(1, this.fPublic);
}
function failFunctionPtrWrongType() public returns(bytes memory) {
return abi.encodeCall(abi.encodeCall, (1, 2, 3, "test"));
}
function failFunctionInternal() public returns(bytes memory) {
return abi.encodeCall(fInternal, (1, "123"));
}
function failFunctionInternalFromVariable() public returns(bytes memory) {
function(uint256, string memory) internal localFunctionPointer = fInternal;
return abi.encodeCall(localFunctionPointer, (1, "123"));
}
function failLibraryPointerCall() public {
abi.encodeCall(L.fInternal, (1, "123"));
abi.encodeCall(L.fExternal, (1, "123"));
}
function failBoundLibraryPointerCall() public returns (bytes memory) {
uint256 x = 1;
return abi.encodeCall(x.fExternal, (1, "123"));
}
function viaBaseDeclaration() public pure returns (bytes memory) {
return abi.encodeCall(C.fPublic, (2));
}
function viaBaseDeclaration2() public pure returns (bytes memory) {
return bytes.concat(
abi.encodeCall(Base.baseFunctionPublic, (1)),
abi.encodeCall(Base.baseFunctionInternal, (1))
);
}
function fileLevelFunction() public pure returns (bytes memory) {
return abi.encodeCall(fileLevel, (2));
}
function createFunction() public pure returns (bytes memory) {
return abi.encodeCall(new Other, (2));
}
}
// ----
// TypeError 5511: (742-743): Expected first argument to be a function pointer, not "int_const 1".
// TypeError 3509: (855-869): Expected regular external function type, or external view on public function. Cannot use special function.
// TypeError 3509: (982-991): Expected regular external function type, or external view on public function. Provided internal function.
// TypeError 3509: (1187-1207): Expected regular external function type, or external view on public function. Provided internal function.
// TypeError 3509: (1286-1297): Expected regular external function type, or external view on public function. Provided internal function.
// TypeError 3509: (1329-1340): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall.
// TypeError 3509: (1471-1482): Expected regular external function type, or external view on public function. Cannot use library functions for abi.encodeCall.
// TypeError 3509: (1592-1601): Expected regular external function type, or external view on public function. Provided internal function. Did you forget to prefix "this."?
// TypeError 3509: (1722-1745): Expected regular external function type, or external view on public function. Provided internal function. Functions from base contracts have to be external.
// TypeError 3509: (1771-1796): Expected regular external function type, or external view on public function. Provided internal function. Functions from base contracts have to be external.
// TypeError 3509: (1902-1911): Expected regular external function type, or external view on public function. Provided internal function.
// TypeError 3509: (2010-2019): Expected regular external function type, or external view on public function. Provided creation function.