mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11026 from ethereum/resolve-keccak
Evaluate ``keccak256(a, const)``, when the value at memory location ``a`` is known at compile time and ``const <= 32``
This commit is contained in:
@@ -317,7 +317,14 @@ YulOptimizerTestCommon::YulOptimizerTestCommon(
|
||||
}},
|
||||
{"fullSuite", [&]() {
|
||||
GasMeter meter(dynamic_cast<EVMDialect const&>(*m_dialect), false, 200);
|
||||
OptimiserSuite::run(*m_dialect, &meter, *m_object, true, solidity::frontend::OptimiserSettings::DefaultYulOptimiserSteps);
|
||||
OptimiserSuite::run(
|
||||
*m_dialect,
|
||||
&meter,
|
||||
*m_object,
|
||||
true,
|
||||
frontend::OptimiserSettings::DefaultYulOptimiserSteps,
|
||||
frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment
|
||||
);
|
||||
}},
|
||||
{"stackLimitEvader", [&]() {
|
||||
disambiguate();
|
||||
@@ -434,6 +441,7 @@ void YulOptimizerTestCommon::updateContext()
|
||||
m_context = make_unique<OptimiserStepContext>(OptimiserStepContext{
|
||||
*m_dialect,
|
||||
*m_nameDispenser,
|
||||
m_reservedIdentifiers
|
||||
m_reservedIdentifiers,
|
||||
frontend::OptimiserSettings::standard().expectedExecutionsPerDeployment
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// The yul code for the following contract
|
||||
// contract C {
|
||||
// uint256[] x;
|
||||
// function f() public { x[10] = 5; }
|
||||
// }
|
||||
|
||||
{
|
||||
let _1 := 0
|
||||
if eq(0x26121ff0, shr(224, calldataload(_1)))
|
||||
{
|
||||
if callvalue() { revert(_1, _1) }
|
||||
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
|
||||
if iszero(lt(0x0a, sload(_1)))
|
||||
{
|
||||
mstore(_1, shl(224, 0x4e487b71))
|
||||
mstore(4, 0x32)
|
||||
revert(_1, 0x24)
|
||||
}
|
||||
mstore(_1, _1)
|
||||
// The hash should be evaluated here
|
||||
sstore(add(keccak256(_1, 0x20), 0x0a), 0x05)
|
||||
}
|
||||
}
|
||||
// ====
|
||||
// EVMVersion: >=constantinople
|
||||
// ----
|
||||
// step: fullSuite
|
||||
//
|
||||
// {
|
||||
// {
|
||||
// let _1 := 0
|
||||
// if eq(0x26121ff0, shr(224, calldataload(_1)))
|
||||
// {
|
||||
// if callvalue() { revert(_1, _1) }
|
||||
// if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
|
||||
// if iszero(lt(0x0a, sload(_1)))
|
||||
// {
|
||||
// mstore(_1, shl(224, 0x4e487b71))
|
||||
// mstore(4, 0x32)
|
||||
// revert(_1, 0x24)
|
||||
// }
|
||||
// mstore(_1, _1)
|
||||
// sstore(0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56d, 0x05)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
mstore(0, 10)
|
||||
/// >>> int.from_bytes(web3.Web3.keccak(int.to_bytes(10, 32, byteorder='big')), byteorder='big')
|
||||
/// 89717814153306320011181716697424560163256864414616650038987186496166826726056
|
||||
let val := keccak256(0, 32)
|
||||
sstore(0, val)
|
||||
}
|
||||
// ----
|
||||
// step: loadResolver
|
||||
//
|
||||
// {
|
||||
// let _1 := 10
|
||||
// let _2 := 0
|
||||
// mstore(_2, _1)
|
||||
// sstore(_2, 89717814153306320011181716697424560163256864414616650038987186496166826726056)
|
||||
// }
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
mstore(0, 30)
|
||||
if calldataload(0) {
|
||||
mstore(0, 20)
|
||||
}
|
||||
let val := keccak256(0, 32)
|
||||
sstore(0, val)
|
||||
}
|
||||
// ----
|
||||
// step: loadResolver
|
||||
//
|
||||
// {
|
||||
// let _1 := 30
|
||||
// let _2 := 0
|
||||
// mstore(_2, _1)
|
||||
// if calldataload(_2) { mstore(_2, 20) }
|
||||
// sstore(_2, keccak256(_2, 32))
|
||||
// }
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
mstore(100, 10)
|
||||
mstore(132, 5)
|
||||
// Won't be evaluated, even though the value is known
|
||||
let val := keccak256(10, 33)
|
||||
sstore(0, val)
|
||||
}
|
||||
// ----
|
||||
// step: loadResolver
|
||||
//
|
||||
// {
|
||||
// let _1 := 10
|
||||
// mstore(100, _1)
|
||||
// mstore(132, 5)
|
||||
// sstore(0, keccak256(_1, 33))
|
||||
// }
|
||||
@@ -0,0 +1,31 @@
|
||||
// import web3
|
||||
// >>> asBytes = int(10).to_bytes(32, byteorder='big')
|
||||
// >>> int.from_bytes(web3.Web3.keccak(asBytes[:31]), byteorder='big')
|
||||
// 9948786400348073077032572701554570401043517428989726124163377057770909578447
|
||||
// >>> int.from_bytes(web3.Web3.keccak(asBytes[:30]), byteorder='big')
|
||||
// 110945455955148346822663466543669633859020391897956790847617069135813044810108
|
||||
// >>> int.from_bytes(web3.Web3.keccak(asBytes[:1]), byteorder='big')
|
||||
// 85131057757245807317576516368191972321038229705283732634690444270750521936266
|
||||
// >>> int.from_bytes(web3.Web3.keccak(b''), byteorder='big')
|
||||
// 89477152217924674838424037953991966239322087453347756267410168184682657981552
|
||||
{
|
||||
mstore(0, 10)
|
||||
sstore(0, keccak256(0, 31))
|
||||
sstore(1, keccak256(0, 30))
|
||||
sstore(2, keccak256(0, 1))
|
||||
sstore(2, keccak256(0, 0))
|
||||
}
|
||||
// ----
|
||||
// step: loadResolver
|
||||
//
|
||||
// {
|
||||
// let _1 := 10
|
||||
// let _2 := 0
|
||||
// mstore(_2, _1)
|
||||
// sstore(_2, 9948786400348073077032572701554570401043517428989726124163377057770909578447)
|
||||
// sstore(1, 110945455955148346822663466543669633859020391897956790847617069135813044810108)
|
||||
// let _13 := 85131057757245807317576516368191972321038229705283732634690444270750521936266
|
||||
// let _14 := 2
|
||||
// sstore(_14, _13)
|
||||
// sstore(_14, 89477152217924674838424037953991966239322087453347756267410168184682657981552)
|
||||
// }
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
let converted := 14
|
||||
let _1 := 50
|
||||
mstore(_1, "abcdefghijklmn")
|
||||
// >>> int.from_bytes(web3.Web3.keccak(text="abcdefghijklmn"), byteorder='big')
|
||||
// 51246744213555520563123611275127692828770413530219146609532820042079541949502
|
||||
|
||||
sstore(0, keccak256(_1, converted))
|
||||
sstore(0, add(mload(_1), 1))
|
||||
}
|
||||
// ----
|
||||
// step: loadResolver
|
||||
//
|
||||
// {
|
||||
// let _1 := 50
|
||||
// let _2 := "abcdefghijklmn"
|
||||
// mstore(_1, _2)
|
||||
// let _3 := 51246744213555520563123611275127692828770413530219146609532820042079541949502
|
||||
// let _4 := 0
|
||||
// sstore(_4, _3)
|
||||
// sstore(_4, add(_2, 1))
|
||||
// }
|
||||
@@ -0,0 +1,22 @@
|
||||
// Test where the location of the memory offset is not known at compile time
|
||||
// >>> import web3
|
||||
// >>> asBytes = int(500).to_bytes(32, byteorder='big')
|
||||
// >>> int.from_bytes(web3.Web3.keccak(asBytes), byteorder='big')
|
||||
// 92647596584187651892918913434663110448935397770592030057655219009846081465370
|
||||
// >>> int.from_bytes(web3.Web3.keccak(asBytes[:16]), byteorder='big')
|
||||
// 110620294328144418057589324861608220015688365608948720310623173341503153578932
|
||||
{
|
||||
let offset := calldataload(0)
|
||||
mstore(offset, 500)
|
||||
sstore(0, keccak256(offset, 32))
|
||||
sstore(1, keccak256(offset, 16))
|
||||
}
|
||||
// ----
|
||||
// step: loadResolver
|
||||
//
|
||||
// {
|
||||
// let _1 := 0
|
||||
// mstore(calldataload(_1), 500)
|
||||
// sstore(_1, 92647596584187651892918913434663110448935397770592030057655219009846081465370)
|
||||
// sstore(1, 110620294328144418057589324861608220015688365608948720310623173341503153578932)
|
||||
// }
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
sstore(0, msize())
|
||||
mstore(0, 10)
|
||||
// Keccak-256 should not be evaluated because of the msize.
|
||||
// Even though, though the code is likely equivalent,
|
||||
// we skip steps if `msize` is present
|
||||
let val := keccak256(0, 32)
|
||||
sstore(1, val)
|
||||
}
|
||||
// ----
|
||||
// step: loadResolver
|
||||
//
|
||||
// {
|
||||
// let _1 := msize()
|
||||
// let _2 := 0
|
||||
// sstore(_2, _1)
|
||||
// mstore(_2, 10)
|
||||
// sstore(1, keccak256(_2, 32))
|
||||
// }
|
||||
Reference in New Issue
Block a user