diff --git a/Changelog.md b/Changelog.md index f42e948ebbce..bfd04e7f7796 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,8 @@ ### 0.8.24 (unreleased) Language Features: + * Introduce global ``block.blobbasefee`` for retrieving the blob base fee of the current block. + * Yul: Introduce builtin ``blobbasefee()`` for retrieving the blob base fee of the current block. Compiler Features: diff --git a/docs/cheatsheet.rst b/docs/cheatsheet.rst index 2f0c1a251f4d..e6b632dae4b6 100644 --- a/docs/cheatsheet.rst +++ b/docs/cheatsheet.rst @@ -56,7 +56,7 @@ Members of ``address`` returns ``false`` on failure - ``
.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure -.. index:: blockhash, block, block;basefree, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp +.. index:: blockhash, block, block;basefee, block;blobbasefee, block;chainid, block;coinbase, block;difficulty, block;gaslimit, block;number, block;prevrandao, block;timestamp .. index:: gasleft, msg;data, msg;sender, msg;sig, msg;value, tx;gasprice, tx;origin Block and Transaction Properties @@ -64,6 +64,7 @@ Block and Transaction Properties - ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks - ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 `_ and `EIP-1559 `_) +- ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) - ``block.chainid`` (``uint``): current chain id - ``block.coinbase`` (``address payable``): current block miner's address - ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` that will be removed in the next breaking release diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4 index 0452f9fa0bb6..b46af906164b 100644 --- a/docs/grammar/SolidityLexer.g4 +++ b/docs/grammar/SolidityLexer.g4 @@ -305,7 +305,7 @@ YulEVMBuiltin: | 'delegatecall' | 'staticcall' | 'return' | 'revert' | 'selfdestruct' | 'invalid' | 'log0' | 'log1' | 'log2' | 'log3' | 'log4' | 'chainid' | 'origin' | 'gasprice' | 'blockhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty' | 'prevrandao' - | 'gaslimit' | 'basefee'; + | 'gaslimit' | 'basefee' | 'blobbasefee'; YulLBrace: '{' -> pushMode(YulMode); YulRBrace: '}' -> popMode; diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index d2256884eb48..f95c9c5290d8 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -67,7 +67,7 @@ There are special variables and functions which always exist in the global namespace and are mainly used to provide information about the blockchain or are general-use utility functions. -.. index:: abi, block, coinbase, difficulty, prevrandao, encode, number, block;number, timestamp, block;timestamp, msg, data, gas, sender, value, gas price, origin +.. index:: abi, block, coinbase, difficulty, prevrandao, encode, number, block;number, timestamp, block;timestamp, block;basefee, block;blobbasefee, msg, data, gas, sender, value, gas price, origin Block and Transaction Properties @@ -75,6 +75,7 @@ Block and Transaction Properties - ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block when ``blocknumber`` is one of the 256 most recent blocks; otherwise returns zero - ``block.basefee`` (``uint``): current block's base fee (`EIP-3198 `_ and `EIP-1559 `_) +- ``block.blobbasefee`` (``uint``): current block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) - ``block.chainid`` (``uint``): current chain id - ``block.coinbase`` (``address payable``): current block miner's address - ``block.difficulty`` (``uint``): current block difficulty (``EVM < Paris``). For other EVM versions it behaves as a deprecated alias for ``block.prevrandao`` (`EIP-4399 `_ ) diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 0adcbf4132bb..60fbd0884a89 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -176,6 +176,8 @@ at each version. Backward compatibility is not guaranteed between each version. - Introduces ``prevrandao()`` and ``block.prevrandao``, and changes the semantics of the now deprecated ``block.difficulty``, disallowing ``difficulty()`` in inline assembly (see `EIP-4399 `_). - ``shanghai`` (**default**) - Smaller code size and gas savings due to the introduction of ``push0`` (see `EIP-3855 `_). +- ``cancun`` + - The block's blob base fee (`EIP-7516 `_ and `EIP-4844 `_) can be accessed via the global ``block.blobbasefee`` or ``blobbasefee()`` in inline assembly. .. index:: ! standard JSON, ! --standard-json .. _compiler-api: diff --git a/docs/yul.rst b/docs/yul.rst index 0e50d137761c..fd792999a993 100644 --- a/docs/yul.rst +++ b/docs/yul.rst @@ -752,8 +752,8 @@ This document does not want to be a full description of the Ethereum virtual mac Please refer to a different document if you are interested in the precise semantics. Opcodes marked with ``-`` do not return a result and all others return exactly one value. -Opcodes marked with ``F``, ``H``, ``B``, ``C``, ``I``, ``L`` and ``P`` are present since Frontier, -Homestead, Byzantium, Constantinople, Istanbul, London or Paris respectively. +Opcodes marked with ``F``, ``H``, ``B``, ``C``, ``I``, ``L``, ``P`` and ``N`` are present since Frontier, +Homestead, Byzantium, Constantinople, Istanbul, London, Paris or Cancun respectively. In the following, ``mem[a...b)`` signifies the bytes of memory starting at position ``a`` up to but not including position ``b`` and ``storage[p]`` signifies the storage contents at slot ``p``. @@ -919,6 +919,8 @@ the ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels a +-------------------------+-----+---+-----------------------------------------------------------------+ | basefee() | | L | current block's base fee (EIP-3198 and EIP-1559) | +-------------------------+-----+---+-----------------------------------------------------------------+ +| blobbasefee() | | N | current block's blob base fee (EIP-7516 and EIP-4844) | ++-------------------------+-----+---+-----------------------------------------------------------------+ | origin() | | F | transaction sender | +-------------------------+-----+---+-----------------------------------------------------------------+ | gasprice() | | F | gas price of the transaction | diff --git a/libevmasm/Instruction.cpp b/libevmasm/Instruction.cpp index 174d12b5e355..23d2667318d9 100644 --- a/libevmasm/Instruction.cpp +++ b/libevmasm/Instruction.cpp @@ -81,6 +81,7 @@ std::map const solidity::evmasm::c_instructions = { "CHAINID", Instruction::CHAINID }, { "SELFBALANCE", Instruction::SELFBALANCE }, { "BASEFEE", Instruction::BASEFEE }, + { "BLOBBASEFEE", Instruction::BLOBBASEFEE }, { "POP", Instruction::POP }, { "MLOAD", Instruction::MLOAD }, { "MSTORE", Instruction::MSTORE }, @@ -230,6 +231,7 @@ static std::map const c_instructionInfo = { Instruction::CHAINID, { "CHAINID", 0, 0, 1, false, Tier::Base } }, { Instruction::SELFBALANCE, { "SELFBALANCE", 0, 0, 1, false, Tier::Low } }, { Instruction::BASEFEE, { "BASEFEE", 0, 0, 1, false, Tier::Base } }, + { Instruction::BLOBBASEFEE, { "BLOBBASEFEE", 0, 0, 1, false, Tier::Base } }, { Instruction::POP, { "POP", 0, 1, 0, false, Tier::Base } }, { Instruction::MLOAD, { "MLOAD", 0, 1, 1, true, Tier::VeryLow } }, { Instruction::MSTORE, { "MSTORE", 0, 2, 0, true, Tier::VeryLow } }, diff --git a/libevmasm/Instruction.h b/libevmasm/Instruction.h index 2fddb11d80ea..cf4f3df1440f 100644 --- a/libevmasm/Instruction.h +++ b/libevmasm/Instruction.h @@ -89,6 +89,7 @@ enum class Instruction: uint8_t CHAINID, ///< get the config's chainid param SELFBALANCE, ///< get balance of the current account BASEFEE, ///< get the block's basefee + BLOBBASEFEE = 0x4a, ///< get the block's blob basefee POP = 0x50, ///< remove item from stack MLOAD, ///< load word from memory diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp index 1971d9d45bb8..fcd948e8b656 100644 --- a/libevmasm/SemanticInformation.cpp +++ b/libevmasm/SemanticInformation.cpp @@ -473,6 +473,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction) case Instruction::CALLVALUE: case Instruction::CHAINID: case Instruction::BASEFEE: + case Instruction::BLOBBASEFEE: case Instruction::GAS: case Instruction::GASPRICE: case Instruction::EXTCODESIZE: diff --git a/libevmasm/SimplificationRule.h b/libevmasm/SimplificationRule.h index e970068fbd7e..50b69d69abc0 100644 --- a/libevmasm/SimplificationRule.h +++ b/libevmasm/SimplificationRule.h @@ -127,6 +127,7 @@ struct EVMBuiltins static auto constexpr CHAINID = PatternGenerator{}; static auto constexpr SELFBALANCE = PatternGenerator{}; static auto constexpr BASEFEE = PatternGenerator{}; + static auto constexpr BLOBBASEFEE = PatternGenerator{}; static auto constexpr POP = PatternGenerator{}; static auto constexpr MLOAD = PatternGenerator{}; static auto constexpr MSTORE = PatternGenerator{}; diff --git a/liblangutil/EVMVersion.cpp b/liblangutil/EVMVersion.cpp index 24ef0673d8b9..78a98d2669cc 100644 --- a/liblangutil/EVMVersion.cpp +++ b/liblangutil/EVMVersion.cpp @@ -49,6 +49,8 @@ bool EVMVersion::hasOpcode(Instruction _opcode) const return hasSelfBalance(); case Instruction::BASEFEE: return hasBaseFee(); + case Instruction::BLOBBASEFEE: + return hasBlobBaseFee(); default: return true; } diff --git a/liblangutil/EVMVersion.h b/liblangutil/EVMVersion.h index b68e9546a1aa..02e4e34f3839 100644 --- a/liblangutil/EVMVersion.h +++ b/liblangutil/EVMVersion.h @@ -101,6 +101,7 @@ class EVMVersion: bool hasChainID() const { return *this >= istanbul(); } bool hasSelfBalance() const { return *this >= istanbul(); } bool hasBaseFee() const { return *this >= london(); } + bool hasBlobBaseFee() const { return *this >= cancun(); } bool hasPrevRandao() const { return *this >= paris(); } bool hasPush0() const { return *this >= shanghai(); } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 5c28d3cd2a78..11812878a5da 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3409,6 +3409,12 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) _memberAccess.location(), "\"basefee\" is not supported by the VM version." ); + else if (memberName == "blobbasefee" && !m_evmVersion.hasBlobBaseFee()) + m_errorReporter.typeError( + 1006_error, + _memberAccess.location(), + "\"blobbasefee\" is not supported by the VM version." + ); else if (memberName == "prevrandao" && !m_evmVersion.hasPrevRandao()) m_errorReporter.warning( 9432_error, diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 7b3e42143804..77538f485b1c 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -4116,7 +4116,8 @@ MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const {"number", TypeProvider::uint256()}, {"gaslimit", TypeProvider::uint256()}, {"chainid", TypeProvider::uint256()}, - {"basefee", TypeProvider::uint256()} + {"basefee", TypeProvider::uint256()}, + {"blobbasefee", TypeProvider::uint256()} }); case Kind::Message: return MemberList::MemberMap({ diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 517f49c35331..c96d8bdea641 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1886,6 +1886,8 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) m_context << Instruction::CHAINID; else if (member == "basefee") m_context << Instruction::BASEFEE; + else if (member == "blobbasefee") + m_context << Instruction::BLOBBASEFEE; else if (member == "data") m_context << u256(0) << Instruction::CALLDATASIZE; else if (member == "sig") diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index a5196366fd30..deed7f80c18c 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -1895,6 +1895,8 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) define(_memberAccess) << "chainid()\n"; else if (member == "basefee") define(_memberAccess) << "basefee()\n"; + else if (member == "blobbasefee") + define(_memberAccess) << "blobbasefee()\n"; else if (member == "data") { IRVariable var(_memberAccess); diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index ed4187540e76..5fc5c55c8501 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -727,6 +727,8 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio errorForVM(7721_error, "only available for Istanbul-compatible"); else if (_instr == evmasm::Instruction::BASEFEE && !m_evmVersion.hasBaseFee()) errorForVM(5430_error, "only available for London-compatible"); + else if (_instr == evmasm::Instruction::BLOBBASEFEE && !m_evmVersion.hasBlobBaseFee()) + errorForVM(6679_error, "only available for Cancun-compatible"); else if (_instr == evmasm::Instruction::PC) m_errorReporter.error( 2450_error, diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 47130fd6c46d..12ffb0f649dd 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -120,6 +120,13 @@ std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) return _instr == evmasm::Instruction::BASEFEE && _evmVersion < langutil::EVMVersion::london(); }; + // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name + // blobbasefee for VMs before cancun. + auto blobBaseFeeException = [&](evmasm::Instruction _instr) -> bool + { + return _instr == evmasm::Instruction::BLOBBASEFEE && _evmVersion < langutil::EVMVersion::cancun(); + }; + // TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name // prevrandao for VMs before paris. auto prevRandaoException = [&](std::string const& _instrName) -> bool @@ -132,7 +139,11 @@ std::set createReservedIdentifiers(langutil::EVMVersion _evmVersion) for (auto const& instr: evmasm::c_instructions) { std::string name = toLower(instr.first); - if (!baseFeeException(instr.second) && !prevRandaoException(name)) + if ( + !baseFeeException(instr.second) && + !blobBaseFeeException(instr.second) && + !prevRandaoException(name) + ) reserved.emplace(name); } reserved += std::vector{ diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 4aff6b85e80d..d4e9e5486665 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -202,7 +202,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "4591", # "There are more than 256 warnings. Ignoring the rest." # Due to 3805, the warning lists look different for different compiler builds. "1834", # Unimplemented feature error, as we do not test it anymore via cmdLineTests - "5430", # basefee being used in inline assembly for EVMVersion < london + "6679", # blobbasefee being used in inline assembly for EVMVersion < cancun "1180", # SMTChecker, covered by CL tests "2339", # SMTChecker, covered by CL tests "2961", # SMTChecker, covered by CL tests diff --git a/scripts/test_antlr_grammar.sh b/scripts/test_antlr_grammar.sh index 4dde11bf7dac..290a044eb847 100755 --- a/scripts/test_antlr_grammar.sh +++ b/scripts/test_antlr_grammar.sh @@ -121,6 +121,8 @@ done < <( grep -v -E 'revertStatement/non_called.sol' | # Skipping a test with "let basefee := ..." grep -v -E 'inlineAssembly/basefee_berlin_function.sol' | + # Skipping a test with "let blobbasefee := ..." + grep -v -E 'inlineAssembly/blobbasefee_shanghai_function.sol' | # Skipping tests with "let prevrandao := ..." grep -v -E 'inlineAssembly/prevrandao_allowed_function_pre_paris.sol' | grep -v -E 'inlineAssembly/prevrandao_disallowed_function_post_paris.sol' | diff --git a/test/EVMHost.cpp b/test/EVMHost.cpp index 2bc1da96525e..813d28fdbf78 100644 --- a/test/EVMHost.cpp +++ b/test/EVMHost.cpp @@ -136,6 +136,8 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm): tx_context.chain_id = evmc::uint256be{1}; // The minimum value of basefee tx_context.block_base_fee = evmc::bytes32{7}; + // The minimum value of blobbasefee + tx_context.blob_base_fee = evmc::bytes32{1}; // Reserve space for recording calls. if (!recorded_calls.capacity()) diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp index 03b2b421b4eb..a26511a0c944 100644 --- a/test/libsolidity/ViewPureChecker.cpp +++ b/test/libsolidity/ViewPureChecker.cpp @@ -92,6 +92,26 @@ BOOST_AUTO_TEST_CASE(environment_access) TypeError, "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" ); + + std::string baseFeeContract = "contract C { function f() view public { block.basefee; } }"; + if (!solidity::test::CommonOptions::get().evmVersion().hasBaseFee()) + CHECK_ERROR( + baseFeeContract, + TypeError, + "\"basefee\" is not supported by the VM version." + ); + else + CHECK_SUCCESS_NO_WARNINGS(baseFeeContract); + + std::string blobBaseFeeContract = "contract C { function f() view public { block.blobbasefee; } }"; + if (!solidity::test::CommonOptions::get().evmVersion().hasBlobBaseFee()) + CHECK_ERROR( + blobBaseFeeContract, + TypeError, + "\"blobbasefee\" is not supported by the VM version." + ); + else + CHECK_SUCCESS_NO_WARNINGS(blobBaseFeeContract); } BOOST_AUTO_TEST_CASE(address_staticcall) diff --git a/test/libsolidity/semanticTests/inlineAssembly/blobbasefee_shanghai_function.sol b/test/libsolidity/semanticTests/inlineAssembly/blobbasefee_shanghai_function.sol new file mode 100644 index 000000000000..d06457133e36 --- /dev/null +++ b/test/libsolidity/semanticTests/inlineAssembly/blobbasefee_shanghai_function.sol @@ -0,0 +1,21 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + let blobbasefee := 999 + ret := blobbasefee + } + } + function g() public pure returns (uint ret) { + assembly { + function blobbasefee() -> r { + r := 1000 + } + ret := blobbasefee() + } + } +} +// ==== +// EVMVersion: <=shanghai +// ---- +// f() -> 999 +// g() -> 1000 diff --git a/test/libsolidity/semanticTests/state/block_blobbasefee.sol b/test/libsolidity/semanticTests/state/block_blobbasefee.sol new file mode 100644 index 000000000000..23da779e40f2 --- /dev/null +++ b/test/libsolidity/semanticTests/state/block_blobbasefee.sol @@ -0,0 +1,17 @@ +contract C { + function f() public view returns (uint) { + return block.blobbasefee; + } + function g() public view returns (uint ret) { + assembly { + ret := blobbasefee() + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// f() -> 1 +// g() -> 1 +// f() -> 1 +// g() -> 1 diff --git a/test/libsolidity/syntaxTests/inlineAssembly/blobbasefee_reserved_cancun.sol b/test/libsolidity/syntaxTests/inlineAssembly/blobbasefee_reserved_cancun.sol new file mode 100644 index 000000000000..0bab7e36c74e --- /dev/null +++ b/test/libsolidity/syntaxTests/inlineAssembly/blobbasefee_reserved_cancun.sol @@ -0,0 +1,12 @@ +contract C { + function f() public view returns (uint ret) { + assembly { + let blobbasefee := sload(0) + ret := blobbasefee + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// ParserError 5568: (98-109): Cannot use builtin function name "blobbasefee" as identifier name. diff --git a/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol b/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol index b723d0aeeb2b..3e1650ad88b9 100644 --- a/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol +++ b/test/libsolidity/syntaxTests/types/magic_block_basefee_error.sol @@ -2,8 +2,15 @@ contract C { function f() public view returns (uint) { return block.basefee; } + function g() public view returns (uint ret) { + assembly { + ret := basefee() + } + } } // ==== -// EVMVersion: <=berlin +// EVMVersion: =berlin // ---- // TypeError 5921: (74-87): "basefee" is not supported by the VM version. +// TypeError 5430: (183-190): The "basefee" instruction is only available for London-compatible VMs (you are currently compiling for "berlin"). +// DeclarationError 8678: (176-192): Variable count for assignment to "ret" does not match number of values (1 vs. 0) diff --git a/test/libsolidity/syntaxTests/types/magic_block_blobbasefee_cancun.sol b/test/libsolidity/syntaxTests/types/magic_block_blobbasefee_cancun.sol new file mode 100644 index 000000000000..a639abda71ee --- /dev/null +++ b/test/libsolidity/syntaxTests/types/magic_block_blobbasefee_cancun.sol @@ -0,0 +1,13 @@ +contract C { + function f() public view returns (uint) { + return block.blobbasefee; + } + function g() public view returns (uint ret) { + assembly { + ret := blobbasefee() + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- diff --git a/test/libsolidity/syntaxTests/types/magic_block_blobbasefee_error.sol b/test/libsolidity/syntaxTests/types/magic_block_blobbasefee_error.sol new file mode 100644 index 000000000000..11a5bd991ae4 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/magic_block_blobbasefee_error.sol @@ -0,0 +1,16 @@ +contract C { + function f() public view returns (uint) { + return block.blobbasefee; + } + function g() public view returns (uint ret) { + assembly { + ret := blobbasefee() + } + } +} +// ==== +// EVMVersion: =shanghai +// ---- +// TypeError 1006: (74-91): "blobbasefee" is not supported by the VM version. +// DeclarationError 4619: (187-198): Function "blobbasefee" not found. +// DeclarationError 8678: (180-200): Variable count for assignment to "ret" does not match number of values (1 vs. 0) diff --git a/test/libsolidity/syntaxTests/viewPureChecker/blobbasefee_not_pure.sol b/test/libsolidity/syntaxTests/viewPureChecker/blobbasefee_not_pure.sol new file mode 100644 index 000000000000..3bace4285c32 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/blobbasefee_not_pure.sol @@ -0,0 +1,13 @@ +contract C { + function f() public pure { + assembly { pop(blobbasefee()) } + } + function g() public pure returns (uint) { + return block.blobbasefee; + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// TypeError 2527: (67-80): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". +// TypeError 2527: (151-168): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_view_cancun.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_view_cancun.sol new file mode 100644 index 000000000000..37380b965df2 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_allowed_view_cancun.sol @@ -0,0 +1,10 @@ +contract C { + function f() public view { + assembly { + pop(blobbasefee()) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- diff --git a/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_cancun.sol b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_cancun.sol new file mode 100644 index 000000000000..5e2265f16274 --- /dev/null +++ b/test/libsolidity/syntaxTests/viewPureChecker/inline_assembly_instructions_disallowed_pure_cancun.sol @@ -0,0 +1,11 @@ +contract C { + function f() public pure { + assembly { + pop(blobbasefee()) + } + } +} +// ==== +// EVMVersion: >=cancun +// ---- +// TypeError 2527: (79-92): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view". diff --git a/test/libyul/yulInterpreterTests/blobbasefee.yul b/test/libyul/yulInterpreterTests/blobbasefee.yul new file mode 100644 index 000000000000..d863b1d8265f --- /dev/null +++ b/test/libyul/yulInterpreterTests/blobbasefee.yul @@ -0,0 +1,10 @@ +{ + sstore(0, blobbasefee()) +} +// ==== +// EVMVersion: >=cancun +// ---- +// Trace: +// Memory dump: +// Storage dump: +// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000001 diff --git a/test/libyul/yulSyntaxTests/blobbasefee_identifier_pre_cancun.yul b/test/libyul/yulSyntaxTests/blobbasefee_identifier_pre_cancun.yul new file mode 100644 index 000000000000..42c1f2c0a680 --- /dev/null +++ b/test/libyul/yulSyntaxTests/blobbasefee_identifier_pre_cancun.yul @@ -0,0 +1,6 @@ +{ + function blobbasefee() {} +} +// ==== +// EVMVersion: <=shanghai +// ---- diff --git a/test/libyul/yulSyntaxTests/blobbasefee_reserved_identifier_post_cancun.yul b/test/libyul/yulSyntaxTests/blobbasefee_reserved_identifier_post_cancun.yul new file mode 100644 index 000000000000..61fa7d7e427a --- /dev/null +++ b/test/libyul/yulSyntaxTests/blobbasefee_reserved_identifier_post_cancun.yul @@ -0,0 +1,7 @@ +{ + function blobbasefee() {} +} +// ==== +// EVMVersion: >=cancun +// ---- +// ParserError 5568: (15-26): Cannot use builtin function name "blobbasefee" as identifier name. diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 79dbc554a292..015924a3b61b 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -233,6 +233,8 @@ u256 EVMInstructionInterpreter::eval( return m_state.chainid; case Instruction::BASEFEE: return m_state.basefee; + case Instruction::BLOBBASEFEE: + return m_state.blobbasefee; case Instruction::EXTCODESIZE: return u256(keccak256(h256(arg[0]))) & 0xffffff; case Instruction::EXTCODEHASH: diff --git a/test/tools/yulInterpreter/Interpreter.h b/test/tools/yulInterpreter/Interpreter.h index 26a8b2701215..66082b5b30f6 100644 --- a/test/tools/yulInterpreter/Interpreter.h +++ b/test/tools/yulInterpreter/Interpreter.h @@ -99,6 +99,8 @@ struct InterpreterState u256 chainid = 0x01; /// The minimum value of basefee: 7 wei. u256 basefee = 0x07; + /// The minimum value of blobbasefee: 1 wei. + u256 blobbasefee = 0x01; /// Log of changes / effects. Sholud be structured data in the future. std::vector trace; /// This is actually an input parameter that more or less limits the runtime.