Adds support for the EVM version "Paris".

Deprecates `block.difficulty` and disallow `difficulty()` in inline assembly for EVM versions >= paris.
The change is due to the renaming introduced by EIP-4399 (see: https://eips.ethereum.org/EIPS/eip-4399).
Introduces `block.prevrandao` in Solidity and `prevrandao()` in inline assembly for EVM versions >= paris.

Co-authored-by: Alex Beregszaszi <alex@rtfs.hu>
Co-authored-by: Daniel <daniel@ekpyron.org>
Co-authored-by: matheusaaguiar <95899911+matheusaaguiar@users.noreply.github.com>
Co-authored-by: Nikola Matić <nikola.matic@ethereum.org>
This commit is contained in:
Rodrigo Q. Saramago
2023-01-23 18:50:36 +00:00
co-authored by Alex Beregszaszi Daniel matheusaaguiar Nikola Matić
parent d70d79af4a
commit ef6ff2f055
114 changed files with 842 additions and 221 deletions
+1 -1
View File
@@ -47,7 +47,7 @@ void ExpressionSimplifier::visit(Expression& _expression)
m_dialect,
[this](YulString _var) { return variableValue(_var); }
))
_expression = match->action().toExpression(debugDataOf(_expression));
_expression = match->action().toExpression(debugDataOf(_expression), evmVersionFromDialect(m_dialect));
if (auto* functionCall = get_if<FunctionCall>(&_expression))
if (optional<evmasm::Instruction> instruction = toEVMInstruction(m_dialect, functionCall->functionName.name))
+1 -1
View File
@@ -102,7 +102,7 @@ Expression KnowledgeBase::simplifyRecursively(Expression _expression)
arg = simplifyRecursively(arg);
if (auto match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_variableValues))
return simplifyRecursively(match->action().toExpression(debugDataOf(_expression)));
return simplifyRecursively(match->action().toExpression(debugDataOf(_expression), langutil::EVMVersion()));
return _expression;
}
+2 -1
View File
@@ -20,6 +20,7 @@
#include <libyul/optimiser/Metrics.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/AST.h>
#include <libyul/Exceptions.h>
@@ -180,7 +181,7 @@ void CodeCost::visit(Expression const& _expression)
void CodeCost::addInstructionCost(evmasm::Instruction _instruction)
{
evmasm::Tier gasPriceTier = evmasm::instructionInfo(_instruction).gasPriceTier;
evmasm::Tier gasPriceTier = evmasm::instructionInfo(_instruction, evmVersionFromDialect(m_dialect)).gasPriceTier;
if (gasPriceTier < evmasm::Tier::VeryLow)
m_cost -= 1;
else if (gasPriceTier < evmasm::Tier::High)
+7
View File
@@ -58,6 +58,13 @@ optional<evmasm::Instruction> yul::toEVMInstruction(Dialect const& _dialect, Yul
return nullopt;
}
langutil::EVMVersion const yul::evmVersionFromDialect(Dialect const& _dialect)
{
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))
return dialect->evmVersion();
return langutil::EVMVersion();
}
void StatementRemover::operator()(Block& _block)
{
util::iterateReplacing(
+5
View File
@@ -26,6 +26,7 @@
#include <libyul/Dialect.h>
#include <libyul/YulString.h>
#include <libyul/optimiser/ASTWalker.h>
#include <liblangutil/EVMVersion.h>
#include <optional>
@@ -49,6 +50,10 @@ bool isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifie
/// Helper function that returns the instruction, if the `_name` is a BuiltinFunction
std::optional<evmasm::Instruction> toEVMInstruction(Dialect const& _dialect, YulString const& _name);
/// Helper function that returns the EVM version from a dialect.
/// It returns the default EVM version if dialect is not an EVMDialect.
langutil::EVMVersion const evmVersionFromDialect(Dialect const& _dialect);
class StatementRemover: public ASTModifier
{
public:
+3 -3
View File
@@ -235,7 +235,7 @@ evmasm::Instruction Pattern::instruction() const
return m_instruction;
}
Expression Pattern::toExpression(shared_ptr<DebugData const> const& _debugData) const
Expression Pattern::toExpression(shared_ptr<DebugData const> const& _debugData, langutil::EVMVersion _evmVersion) const
{
if (matchGroup())
return ASTCopier().translate(matchGroupValue());
@@ -248,9 +248,9 @@ Expression Pattern::toExpression(shared_ptr<DebugData const> const& _debugData)
{
vector<Expression> arguments;
for (auto const& arg: m_arguments)
arguments.emplace_back(arg.toExpression(_debugData));
arguments.emplace_back(arg.toExpression(_debugData, _evmVersion));
string name = util::toLower(instructionInfo(m_instruction).name);
string name = util::toLower(instructionInfo(m_instruction, _evmVersion).name);
return FunctionCall{_debugData,
Identifier{_debugData, YulString{name}},
+1 -1
View File
@@ -131,7 +131,7 @@ public:
/// Turns this pattern into an actual expression. Should only be called
/// for patterns resulting from an action, i.e. with match groups assigned.
Expression toExpression(std::shared_ptr<DebugData const> const& _debugData) const;
Expression toExpression(std::shared_ptr<DebugData const> const& _debugData, langutil::EVMVersion _evmVersion) const;
private:
Expression const& matchGroupValue() const;