mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into breaking
This commit is contained in:
@@ -821,28 +821,6 @@ BOOST_AUTO_TEST_CASE(constructor)
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(blockchain)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
constructor() payable {}
|
||||
function someInfo() public payable returns (uint256 value, address coinbase, uint256 blockNumber) {
|
||||
value = msg.value;
|
||||
coinbase = block.coinbase;
|
||||
blockNumber = block.number;
|
||||
}
|
||||
}
|
||||
)";
|
||||
m_evmcHost->tx_context.block_coinbase = EVMHost::convertToEVMC(h160("0x1212121212121212121212121212121212121212"));
|
||||
m_evmcHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
m_evmcHost->newBlock();
|
||||
compileAndRun(sourceCode, 27);
|
||||
ABI_CHECK(callContractFunctionWithValue("someInfo()", 28), encodeArgs(28, u256("0x1212121212121212121212121212121212121212"), 7));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(send_ether)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@@ -905,25 +883,6 @@ BOOST_AUTO_TEST_CASE(transfer_ether)
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(uncalled_blockhash)
|
||||
{
|
||||
char const* code = R"(
|
||||
contract C {
|
||||
function f() public view returns (bytes32)
|
||||
{
|
||||
return (blockhash)(block.number - 1);
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
compileAndRun(code, 0, "C");
|
||||
bytes result = callContractFunction("f()");
|
||||
BOOST_REQUIRE_EQUAL(result.size(), 32);
|
||||
BOOST_CHECK(result[0] != 0 || result[1] != 0 || result[2] != 0);
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(selfdestruct)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@@ -1381,41 +1340,6 @@ BOOST_AUTO_TEST_CASE(contracts_as_addresses)
|
||||
BOOST_REQUIRE(callContractFunction("getBalance()") == encodeArgs(u256(20 - 5), u256(5)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(gaslimit)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
function f() public returns (uint) {
|
||||
return block.gaslimit;
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
auto result = callContractFunction("f()");
|
||||
ABI_CHECK(result, encodeArgs(gasLimit()));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(gasprice)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
function f() public returns (uint) {
|
||||
return tx.gasprice;
|
||||
}
|
||||
}
|
||||
)";
|
||||
ALSO_VIA_YUL(
|
||||
DISABLE_EWASM_TESTRUN()
|
||||
|
||||
compileAndRun(sourceCode);
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(gasPrice()));
|
||||
)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(blockhash)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
|
||||
@@ -22,6 +22,8 @@ contract C {
|
||||
return data[0];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// fromMemory() -> 0x00
|
||||
// fromCalldata(bytes): 0x40, 0x60, 0x00, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0x00
|
||||
|
||||
@@ -18,6 +18,8 @@ contract C {
|
||||
return array[index];
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// l() -> 0
|
||||
// g(uint256): 70 ->
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public returns (address payable) {
|
||||
return block.coinbase;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0x7878787878787878787878787878787878787878
|
||||
// f() -> 0x7878787878787878787878787878787878787878
|
||||
// f() -> 0x7878787878787878787878787878787878787878
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public returns (uint) {
|
||||
return block.difficulty;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 200000000
|
||||
// f() -> 200000000
|
||||
// f() -> 200000000
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public returns (uint) {
|
||||
return block.gaslimit;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 20000000
|
||||
// f() -> 20000000
|
||||
// f() -> 20000000
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
constructor() {}
|
||||
function f() public returns (uint) {
|
||||
return block.number;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor()
|
||||
// f() -> 2
|
||||
// f() -> 3
|
||||
@@ -0,0 +1,12 @@
|
||||
contract C {
|
||||
constructor() {}
|
||||
function f() public returns (uint) {
|
||||
return block.timestamp;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor() # This is the 1st block #
|
||||
// f() -> 0x1e # This is the 2nd block (each block is "15 seconds") #
|
||||
// f() -> 0x2d # This is the 3rd block #
|
||||
@@ -0,0 +1,23 @@
|
||||
contract C {
|
||||
bytes32 public genesisHash;
|
||||
bytes32 public currentHash;
|
||||
constructor() {
|
||||
require(block.number == 1);
|
||||
genesisHash = blockhash(0);
|
||||
currentHash = blockhash(1);
|
||||
}
|
||||
function f(uint blockNumber) public returns (bytes32) {
|
||||
return blockhash(blockNumber);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// constructor()
|
||||
// genesisHash() -> 0x3737373737373737373737373737373737373737373737373737373737373737
|
||||
// currentHash() -> 0
|
||||
// f(uint256): 0 -> 0x3737373737373737373737373737373737373737373737373737373737373737
|
||||
// f(uint256): 1 -> 0x3737373737373737373737373737373737373737373737373737373737373738
|
||||
// f(uint256): 255 -> 0x00
|
||||
// f(uint256): 256 -> 0x00
|
||||
// f(uint256): 257 -> 0x00
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public returns (bool) {
|
||||
return gasleft() > 0;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> true
|
||||
// f() -> true
|
||||
// f() -> true
|
||||
@@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
function f() public returns (bytes calldata) {
|
||||
return msg.data;
|
||||
}
|
||||
function g(uint,bool) public returns (bytes calldata) {
|
||||
return msg.data;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0x20, 4, 17219911917854084299749778639755835327755045716242581057573779540915269926912
|
||||
// g(uint256,bool): 1234, true -> 0x20, 0x44, 35691323728519381642872894128098848782337736632589179916067422734266033766400, 33268574187263889506619096617382224251268236217415066441681855047532544, 26959946667150639794667015087019630673637144422540572481103610249216
|
||||
@@ -0,0 +1,9 @@
|
||||
contract C {
|
||||
function f() public returns (address payable) {
|
||||
return msg.sender;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0x1212121212121212121212121212120000000012
|
||||
@@ -0,0 +1,13 @@
|
||||
contract C {
|
||||
function f() public returns (bytes4) {
|
||||
return msg.sig;
|
||||
}
|
||||
function g() public returns (bytes4) {
|
||||
return msg.sig;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0x26121ff000000000000000000000000000000000000000000000000000000000
|
||||
// g() -> 0xe2179b8e00000000000000000000000000000000000000000000000000000000
|
||||
@@ -0,0 +1,10 @@
|
||||
contract C {
|
||||
function f() public payable returns (uint) {
|
||||
return msg.value;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0
|
||||
// f(), 12 ether -> 12000000000000000000
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public returns (uint) {
|
||||
return tx.gasprice;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 3000000000
|
||||
// f() -> 3000000000
|
||||
// f() -> 3000000000
|
||||
@@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f() public returns (address payable) {
|
||||
return tx.origin;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0x9292929292929292929292929292929292929292
|
||||
// f() -> 0x9292929292929292929292929292929292929292
|
||||
// f() -> 0x9292929292929292929292929292929292929292
|
||||
@@ -0,0 +1,9 @@
|
||||
contract C {
|
||||
function f() public returns (bytes32) {
|
||||
return (blockhash)(block.number - 1);
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// compileViaYul: also
|
||||
// ----
|
||||
// f() -> 0x3737373737373737373737373737373737373737373737373737373737373738
|
||||
@@ -0,0 +1,16 @@
|
||||
contract C {
|
||||
function f() public view returns (address payable) {
|
||||
return block.coinbase;
|
||||
}
|
||||
function g() public view returns (uint) {
|
||||
return block.difficulty;
|
||||
}
|
||||
function h() public view returns (uint) {
|
||||
return block.gaslimit;
|
||||
}
|
||||
function i() public view returns (uint) {
|
||||
return block.timestamp;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: <istanbul
|
||||
@@ -0,0 +1,16 @@
|
||||
contract C {
|
||||
function f() public view returns (address payable) {
|
||||
return block.coinbase;
|
||||
}
|
||||
function g() public view returns (uint) {
|
||||
return block.difficulty;
|
||||
}
|
||||
function h() public view returns (uint) {
|
||||
return block.gaslimit;
|
||||
}
|
||||
function i() public view returns (uint) {
|
||||
return block.timestamp;
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=istanbul
|
||||
@@ -1,10 +1,98 @@
|
||||
#include <test/tools/ossfuzz/protoToAbiV2.h>
|
||||
|
||||
#include <boost/preprocessor.hpp>
|
||||
|
||||
/// Convenience macros
|
||||
/// Returns a valid Solidity integer width w such that 8 <= w <= 256.
|
||||
#define INTWIDTH(z, n, _ununsed) BOOST_PP_MUL(BOOST_PP_ADD(n, 1), 8)
|
||||
/// Using declaration that aliases long boost multiprecision types with
|
||||
/// s(u)<width> where <width> is a valid Solidity integer width and "s"
|
||||
/// stands for "signed" and "u" for "unsigned".
|
||||
#define USINGDECL(z, n, sign) \
|
||||
using BOOST_PP_CAT(BOOST_PP_IF(sign, s, u), INTWIDTH(z, n,)) = \
|
||||
boost::multiprecision::number< \
|
||||
boost::multiprecision::cpp_int_backend< \
|
||||
INTWIDTH(z, n,), \
|
||||
INTWIDTH(z, n,), \
|
||||
BOOST_PP_IF( \
|
||||
sign, \
|
||||
boost::multiprecision::signed_magnitude, \
|
||||
boost::multiprecision::unsigned_magnitude \
|
||||
), \
|
||||
boost::multiprecision::unchecked, \
|
||||
void \
|
||||
> \
|
||||
>;
|
||||
/// Instantiate the using declarations for signed and unsigned integer types.
|
||||
BOOST_PP_REPEAT(32, USINGDECL, 1)
|
||||
BOOST_PP_REPEAT(32, USINGDECL, 0)
|
||||
/// Case implementation that returns an integer value of the specified type.
|
||||
/// For signed integers, we divide by two because the range for boost multiprecision
|
||||
/// types is double that of Solidity integer types. Example, 8-bit signed boost
|
||||
/// number range is [-255, 255] but Solidity `int8` range is [-128, 127]
|
||||
#define CASEIMPL(z, n, sign) \
|
||||
case INTWIDTH(z, n,): \
|
||||
stream << BOOST_PP_IF( \
|
||||
sign, \
|
||||
integerValue< \
|
||||
BOOST_PP_CAT( \
|
||||
BOOST_PP_IF(sign, s, u), \
|
||||
INTWIDTH(z, n,) \
|
||||
)>(_counter) / 2, \
|
||||
integerValue< \
|
||||
BOOST_PP_CAT( \
|
||||
BOOST_PP_IF(sign, s, u), \
|
||||
INTWIDTH(z, n,) \
|
||||
)>(_counter) \
|
||||
); \
|
||||
break;
|
||||
/// Switch implementation that instantiates case statements for (un)signed
|
||||
/// Solidity integer types.
|
||||
#define SWITCHIMPL(sign) \
|
||||
ostringstream stream; \
|
||||
switch (_intWidth) \
|
||||
{ \
|
||||
BOOST_PP_REPEAT(32, CASEIMPL, sign) \
|
||||
} \
|
||||
return stream.str();
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity;
|
||||
using namespace solidity::util;
|
||||
using namespace solidity::test::abiv2fuzzer;
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename V>
|
||||
static V integerValue(unsigned _counter)
|
||||
{
|
||||
V value = V(
|
||||
u256(solidity::util::keccak256(solidity::util::h256(_counter))) % u256(boost::math::tools::max_value<V>())
|
||||
);
|
||||
if (value % 2 == 0)
|
||||
return value * (-1);
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
static string signedIntegerValue(unsigned _counter, unsigned _intWidth)
|
||||
{
|
||||
SWITCHIMPL(1)
|
||||
}
|
||||
|
||||
static string unsignedIntegerValue(unsigned _counter, unsigned _intWidth)
|
||||
{
|
||||
SWITCHIMPL(0)
|
||||
}
|
||||
|
||||
static string integerValue(unsigned _counter, unsigned _intWidth, bool _signed)
|
||||
{
|
||||
if (_signed)
|
||||
return signedIntegerValue(_counter, _intWidth);
|
||||
else
|
||||
return unsignedIntegerValue(_counter, _intWidth);
|
||||
}
|
||||
}
|
||||
|
||||
string ProtoConverter::getVarDecl(
|
||||
string const& _type,
|
||||
string const& _varName,
|
||||
@@ -1013,11 +1101,7 @@ string ValueGetterVisitor::visit(BoolType const&)
|
||||
|
||||
string ValueGetterVisitor::visit(IntegerType const& _type)
|
||||
{
|
||||
return integerValueAsString(
|
||||
_type.is_signed(),
|
||||
getIntWidth(_type),
|
||||
counter()
|
||||
);
|
||||
return integerValue(counter(), getIntWidth(_type), _type.is_signed());
|
||||
}
|
||||
|
||||
string ValueGetterVisitor::visit(FixedByteType const& _type)
|
||||
@@ -1041,48 +1125,6 @@ string ValueGetterVisitor::visit(DynamicByteArrayType const& _type)
|
||||
);
|
||||
}
|
||||
|
||||
std::string ValueGetterVisitor::integerValueAsString(bool _sign, unsigned _width, unsigned _counter)
|
||||
{
|
||||
if (_sign)
|
||||
return intValueAsString(_width, _counter);
|
||||
else
|
||||
return uintValueAsString(_width, _counter);
|
||||
}
|
||||
|
||||
/* Input(s)
|
||||
* - Unsigned integer to be hashed
|
||||
* - Width of desired uint value
|
||||
* Processing
|
||||
* - Take hash of first parameter and mask it with the max unsigned value for given bit width
|
||||
* Output
|
||||
* - string representation of uint value
|
||||
*/
|
||||
std::string ValueGetterVisitor::uintValueAsString(unsigned _width, unsigned _counter)
|
||||
{
|
||||
solAssert(
|
||||
(_width % 8 == 0),
|
||||
"Proto ABIv2 Fuzzer: Unsigned integer width is not a multiple of 8"
|
||||
);
|
||||
return maskUnsignedIntToHex(_counter, _width/4);
|
||||
}
|
||||
|
||||
/* Input(s)
|
||||
* - counter to be hashed to derive a value for Integer type
|
||||
* - Width of desired int value
|
||||
* Processing
|
||||
* - Take hash of first parameter and mask it with the max signed value for given bit width
|
||||
* Output
|
||||
* - string representation of int value
|
||||
*/
|
||||
std::string ValueGetterVisitor::intValueAsString(unsigned _width, unsigned _counter)
|
||||
{
|
||||
solAssert(
|
||||
(_width % 8 == 0),
|
||||
"Proto ABIv2 Fuzzer: Signed integer width is not a multiple of 8"
|
||||
);
|
||||
return maskUnsignedIntToHex(_counter, ((_width/4) - 1));
|
||||
}
|
||||
|
||||
std::string ValueGetterVisitor::croppedString(
|
||||
unsigned _numBytes,
|
||||
unsigned _counter,
|
||||
@@ -1153,9 +1195,10 @@ std::string ValueGetterVisitor::fixedByteValueAsString(unsigned _width, unsigned
|
||||
|
||||
std::string ValueGetterVisitor::addressValueAsString(unsigned _counter)
|
||||
{
|
||||
return Whiskers(R"(address(<value>))")
|
||||
("value", uintValueAsString(160, _counter))
|
||||
.render();
|
||||
// TODO: Isabelle encoder expects address literal to be exactly
|
||||
// 20 bytes and a hex string.
|
||||
// Example: 0x0102030405060708090a0102030405060708090a
|
||||
return "address(" + maskUnsignedIntToHex(_counter, 40) + ")";
|
||||
}
|
||||
|
||||
std::string ValueGetterVisitor::variableLengthValueAsString(
|
||||
|
||||
@@ -792,9 +792,6 @@ private:
|
||||
return m_counter++;
|
||||
}
|
||||
|
||||
static std::string intValueAsString(unsigned _width, unsigned _counter);
|
||||
static std::string uintValueAsString(unsigned _width, unsigned _counter);
|
||||
static std::string integerValueAsString(bool _sign, unsigned _width, unsigned _counter);
|
||||
static std::string addressValueAsString(unsigned _counter);
|
||||
static std::string fixedByteValueAsString(unsigned _width, unsigned _counter);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user