Merge remote-tracking branch 'origin/develop' into HEAD

This commit is contained in:
chriseth
2020-01-14 16:43:48 +01:00
604 changed files with 4302 additions and 4174 deletions
+22
View File
@@ -1,4 +1,26 @@
[
{
"name": "YulOptimizerRedundantAssignmentBreakContinue",
"summary": "The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.",
"description": "The Yul optimizer has a stage that removes assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to variables declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.",
"introduced": "0.6.0",
"fixed": "0.6.1",
"severity": "medium",
"conditions": {
"yulOptimizer": true
}
},
{
"name": "YulOptimizerRedundantAssignmentBreakContinue0.5",
"summary": "The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.",
"description": "The Yul optimizer has a stage that removes assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to variables declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.",
"introduced": "0.5.8",
"fixed": "0.5.16",
"severity": "low",
"conditions": {
"yulOptimizer": true
}
},
{
"name": "ABIEncoderV2LoopYulOptimizer",
"summary": "If both the experimental ABIEncoderV2 and the experimental Yul optimizer are activated, one component of the Yul optimizer may reuse data in memory that has been changed in the meantime.",
+27 -5
View File
@@ -742,32 +742,46 @@
},
"0.5.10": {
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue0.5",
"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers"
],
"released": "2019-06-25"
},
"0.5.11": {
"bugs": [],
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue0.5"
],
"released": "2019-08-12"
},
"0.5.12": {
"bugs": [],
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue0.5"
],
"released": "2019-10-01"
},
"0.5.13": {
"bugs": [],
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue0.5"
],
"released": "2019-11-14"
},
"0.5.14": {
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue0.5",
"ABIEncoderV2LoopYulOptimizer"
],
"released": "2019-12-09"
},
"0.5.15": {
"bugs": [],
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue0.5"
],
"released": "2019-12-17"
},
"0.5.16": {
"bugs": [],
"released": "2020-01-02"
},
"0.5.2": {
"bugs": [
"SignedArrayStorageCopy",
@@ -840,6 +854,7 @@
},
"0.5.8": {
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue0.5",
"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers",
"SignedArrayStorageCopy",
"ABIEncoderV2StorageArrayWithMultiSlotElement",
@@ -849,6 +864,7 @@
},
"0.5.9": {
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue0.5",
"ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers",
"SignedArrayStorageCopy",
"ABIEncoderV2StorageArrayWithMultiSlotElement"
@@ -856,7 +872,13 @@
"released": "2019-05-28"
},
"0.6.0": {
"bugs": [],
"bugs": [
"YulOptimizerRedundantAssignmentBreakContinue"
],
"released": "2019-12-17"
},
"0.6.1": {
"bugs": [],
"released": "2020-01-02"
}
}
+5 -5
View File
@@ -39,12 +39,12 @@ if they are marked ``virtual``. For details, please see
}
}
contract mortal is owned {
contract destructible is owned {
// This contract inherits the `onlyOwner` modifier from
// `owned` and applies it to the `close` function, which
// causes that calls to `close` only have an effect if
// `owned` and applies it to the `destroy` function, which
// causes that calls to `destroy` only have an effect if
// they are made by the stored owner.
function close() public onlyOwner {
function destroy() public onlyOwner {
selfdestruct(owner);
}
}
@@ -58,7 +58,7 @@ if they are marked ``virtual``. For details, please see
}
}
contract Register is priced, owned {
contract Register is priced, destructible {
mapping (address => bool) registeredAddresses;
uint price;
+28 -28
View File
@@ -51,10 +51,10 @@ Details are given in the following example.
// contracts can access all non-private members including
// internal functions and state variables. These cannot be
// accessed externally via `this`, though.
contract Mortal is Owned {
contract Destructible is Owned {
// The keyword `virtual` means that the function can change
// its behaviour in derived classes ("overriding").
function kill() virtual public {
function destroy() virtual public {
if (msg.sender == owner) selfdestruct(owner);
}
}
@@ -76,9 +76,9 @@ Details are given in the following example.
// Multiple inheritance is possible. Note that `owned` is
// also a base class of `mortal`, yet there is only a single
// also a base class of `Destructible`, yet there is only a single
// instance of `owned` (as for virtual inheritance in C++).
contract Named is Owned, Mortal {
contract Named is Owned, Destructible {
constructor(bytes32 name) public {
Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
NameReg(config.lookup(1)).register(name);
@@ -92,13 +92,13 @@ Details are given in the following example.
// If you want the function to override, you need to use the
// `override` keyword. You need to specify the `virtual` keyword again
// if you want this function to be overridden again.
function kill() public virtual override {
function destroy() public virtual override {
if (msg.sender == owner) {
Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
NameReg(config.lookup(1)).unregister();
// It is still possible to call a specific
// overridden function.
Mortal.kill();
Destructible.destroy();
}
}
}
@@ -107,21 +107,21 @@ Details are given in the following example.
// If a constructor takes an argument, it needs to be
// provided in the header (or modifier-invocation-style at
// the constructor of the derived contract (see below)).
contract PriceFeed is Owned, Mortal, Named("GoldFeed") {
contract PriceFeed is Owned, Destructible, Named("GoldFeed") {
function updateInfo(uint newInfo) public {
if (msg.sender == owner) info = newInfo;
}
// Here, we only specify `override` and not `virtual`.
// This means that contracts deriving from `PriceFeed`
// cannot change the behaviour of `kill` anymore.
function kill() public override(Mortal, Named) { Named.kill(); }
// cannot change the behaviour of `destroy` anymore.
function destroy() public override(Destructible, Named) { Named.destroy(); }
function get() public view returns(uint r) { return info; }
uint info;
}
Note that above, we call ``mortal.kill()`` to "forward" the
Note that above, we call ``Destructible.destroy()`` to "forward" the
destruction request. The way this is done is problematic, as
seen in the following example::
@@ -132,27 +132,27 @@ seen in the following example::
address payable owner;
}
contract mortal is owned {
function kill() public virtual {
contract Destructible is owned {
function destroy() public virtual {
if (msg.sender == owner) selfdestruct(owner);
}
}
contract Base1 is mortal {
function kill() public virtual override { /* do cleanup 1 */ mortal.kill(); }
contract Base1 is Destructible {
function destroy() public virtual override { /* do cleanup 1 */ Destructible.destroy(); }
}
contract Base2 is mortal {
function kill() public virtual override { /* do cleanup 2 */ mortal.kill(); }
contract Base2 is Destructible {
function destroy() public virtual override { /* do cleanup 2 */ Destructible.destroy(); }
}
contract Final is Base1, Base2 {
function kill() public override(Base1, Base2) { Base2.kill(); }
function destroy() public override(Base1, Base2) { Base2.destroy(); }
}
A call to ``Final.kill()`` will call ``Base2.kill`` because we specify it
A call to ``Final.destroy()`` will call ``Base2.destroy`` because we specify it
explicitly in the final override, but this function will bypass
``Base1.kill``. The way around this is to use ``super``::
``Base1.destroy``. The way around this is to use ``super``::
pragma solidity >=0.4.22 <0.8.0;
@@ -161,31 +161,31 @@ explicitly in the final override, but this function will bypass
address payable owner;
}
contract mortal is owned {
function kill() virtual public {
contract Destructible is owned {
function destroy() virtual public {
if (msg.sender == owner) selfdestruct(owner);
}
}
contract Base1 is mortal {
function kill() public virtual override { /* do cleanup 1 */ super.kill(); }
contract Base1 is Destructible {
function destroy() public virtual override { /* do cleanup 1 */ super.destroy(); }
}
contract Base2 is mortal {
function kill() public virtual override { /* do cleanup 2 */ super.kill(); }
contract Base2 is Destructible {
function destroy() public virtual override { /* do cleanup 2 */ super.destroy(); }
}
contract Final is Base1, Base2 {
function kill() public override(Base1, Base2) { super.kill(); }
function destroy() public override(Base1, Base2) { super.destroy(); }
}
If ``Base2`` calls a function of ``super``, it does not simply
call this function on one of its base contracts. Rather, it
calls this function on the next base contract in the final
inheritance graph, so it will call ``Base1.kill()`` (note that
inheritance graph, so it will call ``Base1.destroy()`` (note that
the final inheritance sequence is -- starting with the most
derived contract: Final, Base2, Base1, mortal, owned).
derived contract: Final, Base2, Base1, Destructible, owned).
The actual function that is called when using super is
not known in the context of the class where it is used,
although its type is known. This is similar for ordinary
+1 -1
View File
@@ -164,7 +164,7 @@ The full contract
}
/// destroy the contract and reclaim the leftover funds.
function kill() public {
function shutdown() public {
require(msg.sender == owner);
selfdestruct(msg.sender);
}
+4 -2
View File
@@ -24,10 +24,12 @@ StructDefinition = 'struct' Identifier '{'
ModifierDefinition = 'modifier' Identifier ParameterList? ( 'virtual' | OverrideSpecifier )* Block
ModifierInvocation = Identifier ( '(' ExpressionList? ')' )?
FunctionDefinition = 'function' Identifier? ParameterList
FunctionDefinition = FunctionDescriptor ParameterList
( ModifierInvocation | StateMutability | 'external' | 'public' | 'internal' | 'private' | 'virtual' | OverrideSpecifier )*
( 'returns' ParameterList )? ( ';' | Block )
FunctionDescriptor = 'function' Identifier | 'constructor' | 'fallback' | 'receive'
OverrideSpecifier = 'override' ( '(' UserDefinedTypeName (',' UserDefinedTypeName)* ')' )?
EventDefinition = 'event' Identifier EventParameterList 'anonymous'? ';'
@@ -72,7 +74,7 @@ Statement = IfStatement | TryStatement | WhileStatement | ForStatement | Block |
ExpressionStatement = Expression
IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
TryStatement = 'try' Expression ( 'returns' ParameterList )? Block CatchClause+
CatchClause = 'catch' Identifier? ParameterList Block
CatchClause = 'catch' ( Identifier? ParameterList )? Block
WhileStatement = 'while' '(' Expression ')' Statement
PlaceholderStatement = '_'
SimpleStatement = VariableDefinition | ExpressionStatement
+2 -2
View File
@@ -56,11 +56,11 @@ explanatory purposes.
// Swarm URL is recommended
"urls": [ "bzzr://56ab..." ]
},
"mortal": {
"destructible": {
// Required: keccak256 hash of the source file
"keccak256": "0x234...",
// Required (unless "url" is used): literal contents of the source file
"content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
"content": "contract destructible is owned { function destroy() { if (msg.sender == owner) selfdestruct(owner); } }"
}
},
// Required: Compiler settings
+25 -19
View File
@@ -33,7 +33,7 @@ Solidity Integrations
* `Solidity IDE <https://github.com/System-Glitch/Solidity-IDE>`_
Browser-based IDE with integrated compiler, Ganache and local file system support.
* `Solium <https://github.com/duaraghav8/Solium/>`_
* `Ethlint <https://github.com/duaraghav8/Ethlint>`_
Linter to identify and fix style and security issues in Solidity.
* `Superblocks Lab <https://lab.superblocks.com/>`_
@@ -48,7 +48,7 @@ Solidity Integrations
Plugin for the Atom editor that provides Solidity linting.
* `Atom Solium Linter <https://atom.io/packages/linter-solium>`_
Configurable Solidty linter for Atom using Solium as a base.
Configurable Solidity linter for Atom using Solium (now Ethlint) as a base.
* Eclipse:
@@ -97,23 +97,38 @@ Discontinued:
Solidity Tools
~~~~~~~~~~~~~~
* `ABI to Solidity interface converter <https://gist.github.com/chriseth/8f533d133fa0c15b0d6eaf3ec502c82b>`_
A script for generating contract interfaces from the ABI of a smart contract.
* `Dapp <https://dapp.tools/dapp/>`_
Build tool, package manager, and deployment assistant for Solidity.
* `Solidity REPL <https://github.com/raineorshine/solidity-repl>`_
Try Solidity instantly with a command-line Solidity console.
* `solgraph <https://github.com/raineorshine/solgraph>`_
Visualize Solidity control flow and highlight potential security vulnerabilities.
* `Doxity <https://github.com/DigixGlobal/doxity>`_
Documentation Generator for Solidity.
* `evmdis <https://github.com/Arachnid/evmdis>`_
EVM Disassembler that performs static analysis on the bytecode to provide a higher level of abstraction than raw EVM operations.
* `ABI to solidity interface converter <https://gist.github.com/chriseth/8f533d133fa0c15b0d6eaf3ec502c82b>`_
A script for generating contract interfaces from the ABI of a smart contract.
* `EVM Lab <https://github.com/ethereum/evmlab/>`_
Rich tool package to interact with the EVM. Includes a VM, Etherchain API, and a trace-viewer with gas cost display.
* `leafleth <https://github.com/clemlak/leafleth>`_
A documentation generator for Solidity smart-contracts.
* `PIET <https://piet.slock.it/>`_
A tool to develop, audit and use Solidity smart contracts through a simple graphical interface.
* `solc-select <https://github.com/crytic/solc-select>`_
A script to quickly switch between Solidity compiler versions.
* `Solidity prettier plugin <https://github.com/prettier-solidity/prettier-plugin-solidity>`_
A Prettier Plugin for Solidity.
* `Solidity REPL <https://github.com/raineorshine/solidity-repl>`_
Try Solidity instantly with a command-line Solidity console.
* `solgraph <https://github.com/raineorshine/solgraph>`_
Visualize Solidity control flow and highlight potential security vulnerabilities.
* `Securify <https://securify.ch/>`_
Fully automated online static analyzer for smart contracts, providing a security report based on vulnerability patterns.
@@ -121,18 +136,9 @@ Solidity Tools
* `Sūrya <https://github.com/ConsenSys/surya/>`_
Utility tool for smart contract systems, offering a number of visual outputs and information about the contracts' structure. Also supports querying the function call graph.
* `EVM Lab <https://github.com/ethereum/evmlab/>`_
Rich tool package to interact with the EVM. Includes a VM, Etherchain API, and a trace-viewer with gas cost display.
* `Universal Mutator <https://github.com/agroce/universalmutator>`_
A tool for mutation generation, with configurable rules and support for Solidity and Vyper.
* `PIET <https://piet.slock.it/>`_
A tool to develop, audit and use solidity smart contracts through a simple graphical interface.
.. note::
Information like variable names, comments, and source code formatting is lost in the compilation process and it is not possible to completely recover the original source code. Decompiling smart contracts to view the original source code might not be possible, or the end result that useful.
Third-Party Solidity Parsers and Grammars
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+2 -2
View File
@@ -584,7 +584,7 @@ Yes::
return balanceOf[from];
}
function kill() public onlyowner {
function shutdown() public onlyowner {
selfdestruct(owner);
}
@@ -594,7 +594,7 @@ No::
return balanceOf[from];
}
function kill() onlyowner public {
function shutdown() onlyowner public {
selfdestruct(owner);
}
+7 -4
View File
@@ -180,12 +180,12 @@ Input Description
// `--allow-paths <path>`.
]
},
"mortal":
"destructible":
{
// Optional: keccak256 hash of the source file
"keccak256": "0x234...",
// Required (unless "urls" is used): literal contents of the source file
"content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
"content": "contract destructible is owned { function shutdown() { if (msg.sender == owner) selfdestruct(owner); } }"
}
},
// Optional
@@ -220,8 +220,11 @@ Input Description
"cse": false,
// Optimize representation of literal numbers and strings in code.
"constantOptimizer": false,
// The new Yul optimizer. Mostly operates on the code of ABIEncoderV2.
// It can only be activated through the details here.
// The new Yul optimizer. Mostly operates on the code of ABIEncoderV2
// and inline assembly.
// It is activated together with the global optimizer setting
// and can be deactivated here.
// Before Solidity 0.6.0 it had to be activated through this switch.
"yul": false,
// Tuning options for the Yul optimizer.
"yulDetails": {