fix: corrects _ prefixes

This commit is contained in:
Richie 2022-02-15 18:59:49 -08:00
parent 7f360e61fc
commit beb51068bb
No known key found for this signature in database
GPG Key ID: 7ADF8AF5EC521D17
16 changed files with 185 additions and 185 deletions

View File

@ -45,10 +45,10 @@ Solidity language without a compiler change.
pragma solidity >=0.4.16 <0.9.0; pragma solidity >=0.4.16 <0.9.0;
library GetCode { library GetCode {
function at(address _addr) public view returns (bytes memory code) { function at(address addr) public view returns (bytes memory code) {
assembly { assembly {
// retrieve the size of the code, this needs assembly // retrieve the size of the code, this needs assembly
let size := extcodesize(_addr) let size := extcodesize(addr)
// allocate output byte array - this could also be done without assembly // allocate output byte array - this could also be done without assembly
// by using code = new bytes(size) // by using code = new bytes(size)
code := mload(0x40) code := mload(0x40)
@ -57,7 +57,7 @@ Solidity language without a compiler change.
// store length in memory // store length in memory
mstore(code, size) mstore(code, size)
// actually retrieve the code, this needs assembly // actually retrieve the code, this needs assembly
extcodecopy(_addr, add(code, 0x20), 0, size) extcodecopy(addr, add(code, 0x20), 0, size)
} }
} }
} }
@ -74,43 +74,43 @@ efficient code, for example:
library VectorSum { library VectorSum {
// This function is less efficient because the optimizer currently fails to // This function is less efficient because the optimizer currently fails to
// remove the bounds checks in array access. // remove the bounds checks in array access.
function sumSolidity(uint[] memory _data) public pure returns (uint sum) { function sumSolidity(uint[] memory data) public pure returns (uint sum) {
for (uint i = 0; i < _data.length; ++i) for (uint i = 0; i < data.length; ++i)
sum += _data[i]; sum += data[i];
} }
// We know that we only access the array in bounds, so we can avoid the check. // We know that we only access the array in bounds, so we can avoid the check.
// 0x20 needs to be added to an array because the first slot contains the // 0x20 needs to be added to an array because the first slot contains the
// array length. // array length.
function sumAsm(uint[] memory _data) public pure returns (uint sum) { function sumAsm(uint[] memory data) public pure returns (uint sum) {
for (uint i = 0; i < _data.length; ++i) { for (uint i = 0; i < data.length; ++i) {
assembly { assembly {
sum := add(sum, mload(add(add(_data, 0x20), mul(i, 0x20)))) sum := add(sum, mload(add(add(data, 0x20), mul(i, 0x20))))
} }
} }
} }
// Same as above, but accomplish the entire code within inline assembly. // Same as above, but accomplish the entire code within inline assembly.
function sumPureAsm(uint[] memory _data) public pure returns (uint sum) { function sumPureAsm(uint[] memory data) public pure returns (uint sum) {
assembly { assembly {
// Load the length (first 32 bytes) // Load the length (first 32 bytes)
let len := mload(_data) let len := mload(data)
// Skip over the length field. // Skip over the length field.
// //
// Keep temporary variable so it can be incremented in place. // Keep temporary variable so it can be incremented in place.
// //
// NOTE: incrementing _data would result in an unusable // NOTE: incrementing data would result in an unusable
// _data variable after this assembly block // data variable after this assembly block
let data := add(_data, 0x20) let dataElementLocation := add(data, 0x20)
// Iterate until the bound is not met. // Iterate until the bound is not met.
for for
{ let end := add(data, mul(len, 0x20)) } { let end := add(dataElementLocation, mul(len, 0x20)) }
lt(data, end) lt(dataElementLocation, end)
{ data := add(data, 0x20) } { data := add(dataElementLocation, 0x20) }
{ {
sum := add(sum, mload(data)) sum := add(sum, mload(dataElementLocation))
} }
} }
} }

View File

@ -163,9 +163,9 @@ restrictions highly readable.
// prepend a check that only passes // prepend a check that only passes
// if the function is called from // if the function is called from
// a certain address. // a certain address.
modifier onlyBy(address _account) modifier onlyBy(address account)
{ {
if (msg.sender != _account) if (msg.sender != account)
revert Unauthorized(); revert Unauthorized();
// Do not forget the "_;"! It will // Do not forget the "_;"! It will
// be replaced by the actual function // be replaced by the actual function
@ -173,17 +173,17 @@ restrictions highly readable.
_; _;
} }
/// Make `_newOwner` the new owner of this /// Make `newOwner` the new owner of this
/// contract. /// contract.
function changeOwner(address _newOwner) function changeOwner(address newOwner)
public public
onlyBy(owner) onlyBy(owner)
{ {
owner = _newOwner; owner = newOwner;
} }
modifier onlyAfter(uint _time) { modifier onlyAfter(uint time) {
if (block.timestamp < _time) if (block.timestamp < time)
revert TooEarly(); revert TooEarly();
_; _;
} }
@ -205,21 +205,21 @@ restrictions highly readable.
// refunded, but only after the function body. // refunded, but only after the function body.
// This was dangerous before Solidity version 0.4.0, // This was dangerous before Solidity version 0.4.0,
// where it was possible to skip the part after `_;`. // where it was possible to skip the part after `_;`.
modifier costs(uint _amount) { modifier costs(uint amount) {
if (msg.value < _amount) if (msg.value < amount)
revert NotEnoughEther(); revert NotEnoughEther();
_; _;
if (msg.value > _amount) if (msg.value > amount)
payable(msg.sender).transfer(msg.value - _amount); payable(msg.sender).transfer(msg.value - amount);
} }
function forceOwnerChange(address _newOwner) function forceOwnerChange(address newOwner)
public public
payable payable
costs(200 ether) costs(200 ether)
{ {
owner = _newOwner; owner = newOwner;
// just some example condition // just some example condition
if (uint160(owner) & 0 == 1) if (uint160(owner) & 0 == 1)
// This did not refund for Solidity // This did not refund for Solidity
@ -315,8 +315,8 @@ function finishes.
uint public creationTime = block.timestamp; uint public creationTime = block.timestamp;
modifier atStage(Stages _stage) { modifier atStage(Stages stage_) {
if (stage != _stage) if (stage != stage_)
revert FunctionInvalidAtThisStage(); revert FunctionInvalidAtThisStage();
_; _;
} }

View File

@ -41,14 +41,14 @@ Not all types for constants and immutables are implemented at this time. The onl
uint immutable maxBalance; uint immutable maxBalance;
address immutable owner = msg.sender; address immutable owner = msg.sender;
constructor(uint _decimals, address _reference) { constructor(uint decimals_, address ref) {
decimals = _decimals; decimals = decimals_;
// Assignments to immutables can even access the environment. // Assignments to immutables can even access the environment.
maxBalance = _reference.balance; maxBalance = ref.balance;
} }
function isBalanceTooHigh(address _other) public view returns (bool) { function isBalanceTooHigh(address other) public view returns (bool) {
return _other.balance > maxBalance; return other.balance > maxBalance;
} }
} }

View File

@ -48,7 +48,7 @@ This means that cyclic creation dependencies are impossible.
// This is the constructor which registers the // This is the constructor which registers the
// creator and the assigned name. // creator and the assigned name.
constructor(bytes32 _name) { constructor(bytes32 name_) {
// State variables are accessed via their name // State variables are accessed via their name
// and not via e.g. `this.owner`. Functions can // and not via e.g. `this.owner`. Functions can
// be accessed directly or through `this.f`, // be accessed directly or through `this.f`,
@ -65,7 +65,7 @@ This means that cyclic creation dependencies are impossible.
// no real way to verify that. // no real way to verify that.
// This does not create a new contract. // This does not create a new contract.
creator = TokenCreator(msg.sender); creator = TokenCreator(msg.sender);
name = _name; name = name_;
} }
function changeName(bytes32 newName) public { function changeName(bytes32 newName) public {

View File

@ -80,18 +80,18 @@ four indexed arguments rather than three.
contract ClientReceipt { contract ClientReceipt {
event Deposit( event Deposit(
address indexed _from, address indexed from,
bytes32 indexed _id, bytes32 indexed id,
uint _value uint value
); );
function deposit(bytes32 _id) public payable { function deposit(bytes32 id) public payable {
// Events are emitted using `emit`, followed by // Events are emitted using `emit`, followed by
// the name of the event and the arguments // the name of the event and the arguments
// (if any) in parentheses. Any such invocation // (if any) in parentheses. Any such invocation
// (even deeply nested) can be detected from // (even deeply nested) can be detected from
// the JavaScript API by filtering for `Deposit`. // the JavaScript API by filtering for `Deposit`.
emit Deposit(msg.sender, _id, msg.value); emit Deposit(msg.sender, id, msg.value);
} }
} }
@ -126,9 +126,9 @@ The output of the above looks like the following (trimmed):
{ {
"returnValues": { "returnValues": {
"_from": "0x1111…FFFFCCCC", "from": "0x1111…FFFFCCCC",
"_id": "0x50…sd5adb20", "id": "0x50…sd5adb20",
"_value": "0x420042" "value": "0x420042"
}, },
"raw": { "raw": {
"data": "0x7f…91385", "data": "0x7f…91385",

View File

@ -72,8 +72,8 @@ if they are marked ``virtual``. For details, please see
registeredAddresses[msg.sender] = true; registeredAddresses[msg.sender] = true;
} }
function changePrice(uint _price) public onlyOwner { function changePrice(uint price_) public onlyOwner {
price = _price; price = price_;
} }
} }

View File

@ -17,17 +17,17 @@ that call them, similar to internal library functions.
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.1 <0.9.0; pragma solidity >=0.7.1 <0.9.0;
function sum(uint[] memory _arr) pure returns (uint s) { function sum(uint[] memory arr) pure returns (uint s) {
for (uint i = 0; i < _arr.length; i++) for (uint i = 0; i < arr.length; i++)
s += _arr[i]; s += arr[i];
} }
contract ArrayExample { contract ArrayExample {
bool found; bool found;
function f(uint[] memory _arr) public { function f(uint[] memory arr) public {
// This calls the free function internally. // This calls the free function internally.
// The compiler will add its code to the contract. // The compiler will add its code to the contract.
uint s = sum(_arr); uint s = sum(arr);
require(s >= 10); require(s >= 10);
found = true; found = true;
} }
@ -65,8 +65,8 @@ with two integers, you would use something like the following:
contract Simple { contract Simple {
uint sum; uint sum;
function taker(uint _a, uint _b) public { function taker(uint a, uint b) public {
sum = _a + _b; sum = a + b;
} }
} }
@ -99,13 +99,13 @@ two integers passed as function parameters, then you use something like:
pragma solidity >=0.4.16 <0.9.0; pragma solidity >=0.4.16 <0.9.0;
contract Simple { contract Simple {
function arithmetic(uint _a, uint _b) function arithmetic(uint a, uint b)
public public
pure pure
returns (uint sum, uint product) returns (uint sum, uint product)
{ {
sum = _a + _b; sum = a + b;
product = _a * _b; product = a * b;
} }
} }
@ -126,12 +126,12 @@ statement:
pragma solidity >=0.4.16 <0.9.0; pragma solidity >=0.4.16 <0.9.0;
contract Simple { contract Simple {
function arithmetic(uint _a, uint _b) function arithmetic(uint a, uint b)
public public
pure pure
returns (uint sum, uint product) returns (uint sum, uint product)
{ {
return (_a + _b, _a * _b); return (a + b, a * b);
} }
} }
@ -362,7 +362,7 @@ Fallback Function
----------------- -----------------
A contract can have at most one ``fallback`` function, declared using either ``fallback () external [payable]`` A contract can have at most one ``fallback`` function, declared using either ``fallback () external [payable]``
or ``fallback (bytes calldata _input) external [payable] returns (bytes memory _output)`` or ``fallback (bytes calldata input) external [payable] returns (bytes memory output)``
(both without the ``function`` keyword). (both without the ``function`` keyword).
This function must have ``external`` visibility. A fallback function can be virtual, can override This function must have ``external`` visibility. A fallback function can be virtual, can override
and can have modifiers. and can have modifiers.
@ -373,8 +373,8 @@ all and there is no :ref:`receive Ether function <receive-ether-function>`.
The fallback function always receives data, but in order to also receive Ether The fallback function always receives data, but in order to also receive Ether
it must be marked ``payable``. it must be marked ``payable``.
If the version with parameters is used, ``_input`` will contain the full data sent to the contract If the version with parameters is used, ``input`` will contain the full data sent to the contract
(equal to ``msg.data``) and can return data in ``_output``. The returned data will not be (equal to ``msg.data``) and can return data in ``output``. The returned data will not be
ABI-encoded. Instead it will be returned without modifications (not even padding). ABI-encoded. Instead it will be returned without modifications (not even padding).
In the worst case, if a payable fallback function is also used in In the worst case, if a payable fallback function is also used in
@ -397,7 +397,7 @@ operations as long as there is enough gas passed on to it.
for the function selector and then for the function selector and then
you can use ``abi.decode`` together with the array slice syntax to you can use ``abi.decode`` together with the array slice syntax to
decode ABI-encoded data: decode ABI-encoded data:
``(c, d) = abi.decode(_input[4:], (uint256, uint256));`` ``(c, d) = abi.decode(input[4:], (uint256, uint256));``
Note that this should only be used as a last resort and Note that this should only be used as a last resort and
proper functions should be used instead. proper functions should be used instead.
@ -486,13 +486,13 @@ The following example shows overloading of the function
pragma solidity >=0.4.16 <0.9.0; pragma solidity >=0.4.16 <0.9.0;
contract A { contract A {
function f(uint _in) public pure returns (uint out) { function f(uint value) public pure returns (uint out) {
out = _in; out = value;
} }
function f(uint _in, bool _really) public pure returns (uint out) { function f(uint value, bool really) public pure returns (uint out) {
if (_really) if (really)
out = _in; out = value;
} }
} }
@ -506,12 +506,12 @@ externally visible functions differ by their Solidity types but not by their ext
// This will not compile // This will not compile
contract A { contract A {
function f(B _in) public pure returns (B out) { function f(B value) public pure returns (B out) {
out = _in; out = value;
} }
function f(address _in) public pure returns (address out) { function f(address value) public pure returns (address out) {
out = _in; out = value;
} }
} }
@ -539,12 +539,12 @@ candidate, resolution fails.
pragma solidity >=0.4.16 <0.9.0; pragma solidity >=0.4.16 <0.9.0;
contract A { contract A {
function f(uint8 _in) public pure returns (uint8 out) { function f(uint8 val) public pure returns (uint8 out) {
out = _in; out = val;
} }
function f(uint256 _in) public pure returns (uint256 out) { function f(uint256 val) public pure returns (uint256 out) {
out = _in; out = val;
} }
} }

View File

@ -421,8 +421,8 @@ equivalent to ``constructor() {}``. For example:
abstract contract A { abstract contract A {
uint public a; uint public a;
constructor(uint _a) { constructor(uint a_) {
a = _a; a = a_;
} }
} }
@ -459,7 +459,7 @@ derived contracts need to specify all of them. This can be done in two ways:
contract Base { contract Base {
uint x; uint x;
constructor(uint _x) { x = _x; } constructor(uint x_) { x = x_; }
} }
// Either directly specify in the inheritance list... // Either directly specify in the inheritance list...
@ -469,12 +469,12 @@ derived contracts need to specify all of them. This can be done in two ways:
// or through a "modifier" of the derived constructor. // or through a "modifier" of the derived constructor.
contract Derived2 is Base { contract Derived2 is Base {
constructor(uint _y) Base(_y * _y) {} constructor(uint y) Base(y * y) {}
} }
One way is directly in the inheritance list (``is Base(7)``). The other is in One way is directly in the inheritance list (``is Base(7)``). The other is in
the way a modifier is invoked as part of the way a modifier is invoked as part of
the derived constructor (``Base(_y * _y)``). The first way to the derived constructor (``Base(y * y)``). The first way to
do it is more convenient if the constructor argument is a do it is more convenient if the constructor argument is a
constant and defines the behaviour of the contract or constant and defines the behaviour of the contract or
describes it. The second way has to be used if the describes it. The second way has to be used if the

View File

@ -146,16 +146,16 @@ custom types without the overhead of external function calls:
r.limbs[0] = x; r.limbs[0] = x;
} }
function add(bigint memory _a, bigint memory _b) internal pure returns (bigint memory r) { function add(bigint memory a, bigint memory b) internal pure returns (bigint memory r) {
r.limbs = new uint[](max(_a.limbs.length, _b.limbs.length)); r.limbs = new uint[](max(a.limbs.length, b.limbs.length));
uint carry = 0; uint carry = 0;
for (uint i = 0; i < r.limbs.length; ++i) { for (uint i = 0; i < r.limbs.length; ++i) {
uint a = limb(_a, i); uint limbA = limb(a, i);
uint b = limb(_b, i); uint limbB = limb(b, i);
unchecked { unchecked {
r.limbs[i] = a + b + carry; r.limbs[i] = limbA + limbB + carry;
if (a + b < a || (a + b == type(uint).max && carry > 0)) if (limbA + limbB < limbA || (limbA + limbB == type(uint).max && carry > 0))
carry = 1; carry = 1;
else else
carry = 0; carry = 0;
@ -172,8 +172,8 @@ custom types without the overhead of external function calls:
} }
} }
function limb(bigint memory _a, uint _limb) internal pure returns (uint) { function limb(bigint memory a, uint index) internal pure returns (uint) {
return _limb < _a.limbs.length ? _a.limbs[_limb] : 0; return index < a.limbs.length ? a.limbs[index] : 0;
} }
function max(uint a, uint b) private pure returns (uint) { function max(uint a, uint b) private pure returns (uint) {

View File

@ -128,13 +128,13 @@ In this example, we will use a library.
data.push(value); data.push(value);
} }
function replace(uint _old, uint _new) public { function replace(uint from, uint to) public {
// This performs the library function call // This performs the library function call
uint index = data.indexOf(_old); uint index = data.indexOf(from);
if (index == type(uint).max) if (index == type(uint).max)
data.push(_new); data.push(to);
else else
data[index] = _new; data[index] = to;
} }
} }

View File

@ -168,8 +168,8 @@ following:
.. code-block:: solidity .. code-block:: solidity
function balances(address _account) external view returns (uint) { function balances(address account) external view returns (uint) {
return balances[_account]; return balances[account];
} }
You can use this function to query the balance of a single account. You can use this function to query the balance of a single account.

View File

@ -74,8 +74,8 @@ hiding new and different behavior in existing code.
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0; pragma solidity >=0.7.0;
contract C { contract C {
function f(uint _a) public pure mod() returns (uint _r) { function f(uint a) public pure mod() returns (uint r) {
_r = _a++; r = a++;
} }
modifier mod() { _; _; } modifier mod() { _; _; }
} }
@ -166,7 +166,7 @@ This causes differences in some contracts, for example:
contract C { contract C {
bytes x; bytes x;
function f() public returns (uint _r) { function f() public returns (uint r) {
bytes memory m = "tmp"; bytes memory m = "tmp";
assembly { assembly {
mstore(m, 8) mstore(m, 8)
@ -174,7 +174,7 @@ This causes differences in some contracts, for example:
} }
x = m; x = m;
assembly { assembly {
_r := sload(x.slot) r := sload(x.slot)
} }
} }
} }
@ -197,8 +197,8 @@ This causes differences in some contracts, for example:
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.1; pragma solidity >=0.8.1;
contract C { contract C {
function preincr_u8(uint8 _a) public pure returns (uint8) { function preincr_u8(uint8 a) public pure returns (uint8) {
return ++_a + _a; return ++a + a;
} }
} }
@ -218,11 +218,11 @@ This causes differences in some contracts, for example:
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.1; pragma solidity >=0.8.1;
contract C { contract C {
function add(uint8 _a, uint8 _b) public pure returns (uint8) { function add(uint8 a, uint8 b) public pure returns (uint8) {
return _a + _b; return a + b;
} }
function g(uint8 _a, uint8 _b) public pure returns (uint8) { function g(uint8 a, uint8 b) public pure returns (uint8) {
return add(++_a + ++_b, _a + _b); return add(++a + ++b, a + b);
} }
} }
@ -321,13 +321,13 @@ For example:
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.1; pragma solidity >=0.8.1;
contract C { contract C {
function f(uint8 _a) public pure returns (uint _r1, uint _r2) function f(uint8 a) public pure returns (uint r1, uint r2)
{ {
_a = ~_a; a = ~a;
assembly { assembly {
_r1 := _a r1 := a
} }
_r2 = _a; r2 = a;
} }
} }
@ -336,6 +336,6 @@ The function ``f(1)`` returns the following values:
- Old code generator: (``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) - Old code generator: (``fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe``, ``00000000000000000000000000000000000000000000000000000000000000fe``)
- New code generator: (``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``) - New code generator: (``00000000000000000000000000000000000000000000000000000000000000fe``, ``00000000000000000000000000000000000000000000000000000000000000fe``)
Note that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``_a = ~_a``). Note that, unlike the new code generator, the old code generator does not perform a cleanup after the bit-not assignment (``a = ~a``).
This results in different values being assigned (within the inline assembly block) to return value ``_r1`` between the old and new code generators. This results in different values being assigned (within the inline assembly block) to return value ``r1`` between the old and new code generators.
However, both code generators perform a cleanup before the new value of ``_a`` is assigned to ``_r2``. However, both code generators perform a cleanup before the new value of ``a`` is assigned to ``r2``.

View File

@ -210,9 +210,9 @@ using a second proxy:
contract ProxyWithMoreFunctionality { contract ProxyWithMoreFunctionality {
PermissionlessProxy proxy; PermissionlessProxy proxy;
function callOther(address _addr, bytes memory _payload) public function callOther(address addr, bytes memory payload) public
returns (bool, bytes memory) { returns (bool, bytes memory) {
return proxy.callOther(_addr, _payload); return proxy.callOther(addr, payload);
} }
// Other functions and other functionality // Other functions and other functionality
} }
@ -220,9 +220,9 @@ using a second proxy:
// This is the full contract, it has no other functionality and // This is the full contract, it has no other functionality and
// requires no privileges to work. // requires no privileges to work.
contract PermissionlessProxy { contract PermissionlessProxy {
function callOther(address _addr, bytes memory _payload) public function callOther(address addr, bytes memory payload) public
returns (bool, bytes memory) { returns (bool, bytes memory) {
return _addr.call(_payload); return addr.call(payload);
} }
} }
@ -331,17 +331,17 @@ field of a ``struct`` that is the base type of a dynamic storage array. The
contract Map { contract Map {
mapping (uint => uint)[] array; mapping (uint => uint)[] array;
function allocate(uint _newMaps) public { function allocate(uint newMaps) public {
for (uint i = 0; i < _newMaps; i++) for (uint i = 0; i < newMaps; i++)
array.push(); array.push();
} }
function writeMap(uint _map, uint _key, uint _value) public { function writeMap(uint map, uint key, uint value) public {
array[_map][_key] = _value; array[map][key] = value;
} }
function readMap(uint _map, uint _key) public view returns (uint) { function readMap(uint map, uint key) public view returns (uint) {
return array[_map][_key]; return array[map][key];
} }
function eraseMaps() public { function eraseMaps() public {

View File

@ -82,12 +82,12 @@ Overflow
uint immutable x; uint immutable x;
uint immutable y; uint immutable y;
function add(uint _x, uint _y) internal pure returns (uint) { function add(uint x_, uint y_) internal pure returns (uint) {
return _x + _y; return x_ + y_;
} }
constructor(uint _x, uint _y) { constructor(uint x_, uint y_) {
(x, y) = (_x, _y); (x, y) = (x_, y_);
} }
function stateAdd() public view returns (uint) { function stateAdd() public view returns (uint) {
@ -116,7 +116,7 @@ Here, it reports the following:
Overflow.add(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935) -- internal call Overflow.add(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935) -- internal call
--> o.sol:9:20: --> o.sol:9:20:
| |
9 | return _x + _y; 9 | return x_ + y_;
| ^^^^^^^ | ^^^^^^^
If we add ``require`` statements that filter out overflow cases, If we add ``require`` statements that filter out overflow cases,
@ -131,12 +131,12 @@ the SMTChecker proves that no overflow is reachable (by not reporting warnings):
uint immutable x; uint immutable x;
uint immutable y; uint immutable y;
function add(uint _x, uint _y) internal pure returns (uint) { function add(uint x_, uint y_) internal pure returns (uint) {
return _x + _y; return x_ + y_;
} }
constructor(uint _x, uint _y) { constructor(uint x_, uint y_) {
(x, y) = (_x, _y); (x, y) = (x_, y_);
} }
function stateAdd() public view returns (uint) { function stateAdd() public view returns (uint) {
@ -155,7 +155,7 @@ An assertion represents an invariant in your code: a property that must be true
The code below defines a function ``f`` that guarantees no overflow. The code below defines a function ``f`` that guarantees no overflow.
Function ``inv`` defines the specification that ``f`` is monotonically increasing: Function ``inv`` defines the specification that ``f`` is monotonically increasing:
for every possible pair ``(_a, _b)``, if ``_b > _a`` then ``f(_b) > f(_a)``. for every possible pair ``(a, b)``, if ``b > a`` then ``f(b) > f(a)``.
Since ``f`` is indeed monotonically increasing, the SMTChecker proves that our Since ``f`` is indeed monotonically increasing, the SMTChecker proves that our
property is correct. You are encouraged to play with the property and the function property is correct. You are encouraged to play with the property and the function
definition to see what results come out! definition to see what results come out!
@ -166,14 +166,14 @@ definition to see what results come out!
pragma solidity >=0.8.0; pragma solidity >=0.8.0;
contract Monotonic { contract Monotonic {
function f(uint _x) internal pure returns (uint) { function f(uint x) internal pure returns (uint) {
require(_x < type(uint128).max); require(x < type(uint128).max);
return _x * 42; return x * 42;
} }
function inv(uint _a, uint _b) public pure { function inv(uint a, uint b) public pure {
require(_b > _a); require(b > a);
assert(f(_b) > f(_a)); assert(f(b) > f(a));
} }
} }
@ -188,14 +188,14 @@ equal every element in the array.
pragma solidity >=0.8.0; pragma solidity >=0.8.0;
contract Max { contract Max {
function max(uint[] memory _a) public pure returns (uint) { function max(uint[] memory a) public pure returns (uint) {
uint m = 0; uint m = 0;
for (uint i = 0; i < _a.length; ++i) for (uint i = 0; i < a.length; ++i)
if (_a[i] > m) if (a[i] > m)
m = _a[i]; m = a[i];
for (uint i = 0; i < _a.length; ++i) for (uint i = 0; i < a.length; ++i)
assert(m >= _a[i]); assert(m >= a[i]);
return m; return m;
} }
@ -222,15 +222,15 @@ For example, changing the code to
pragma solidity >=0.8.0; pragma solidity >=0.8.0;
contract Max { contract Max {
function max(uint[] memory _a) public pure returns (uint) { function max(uint[] memory a) public pure returns (uint) {
require(_a.length >= 5); require(a.length >= 5);
uint m = 0; uint m = 0;
for (uint i = 0; i < _a.length; ++i) for (uint i = 0; i < a.length; ++i)
if (_a[i] > m) if (a[i] > m)
m = _a[i]; m = a[i];
for (uint i = 0; i < _a.length; ++i) for (uint i = 0; i < a.length; ++i)
assert(m > _a[i]); assert(m > a[i]);
return m; return m;
} }
@ -243,7 +243,7 @@ gives us:
Warning: CHC: Assertion violation happens here. Warning: CHC: Assertion violation happens here.
Counterexample: Counterexample:
_a = [0, 0, 0, 0, 0] a = [0, 0, 0, 0, 0]
= 0 = 0
Transaction trace: Transaction trace:
@ -251,7 +251,7 @@ gives us:
Test.max([0, 0, 0, 0, 0]) Test.max([0, 0, 0, 0, 0])
--> max.sol:14:4: --> max.sol:14:4:
| |
14 | assert(m > _a[i]); 14 | assert(m > a[i]);
State Properties State Properties
@ -383,9 +383,9 @@ anything, including reenter the caller contract.
Unknown immutable unknown; Unknown immutable unknown;
constructor(Unknown _u) { constructor(Unknown u) {
require(address(_u) != address(0)); require(address(u) != address(0));
unknown = _u; unknown = u;
} }
modifier mutex { modifier mutex {
@ -395,8 +395,8 @@ anything, including reenter the caller contract.
lock = false; lock = false;
} }
function set(uint _x) mutex public { function set(uint x_) mutex public {
x = _x; x = x_;
} }
function run() mutex public { function run() mutex public {
@ -754,15 +754,15 @@ not mean loss of proving power.
{ {
function f( function f(
bytes32 hash, bytes32 hash,
uint8 _v1, uint8 _v2, uint8 v1, uint8 v2,
bytes32 _r1, bytes32 _r2, bytes32 r1, bytes32 r2,
bytes32 _s1, bytes32 _s2 bytes32 s1, bytes32 s2
) public pure returns (address) { ) public pure returns (address) {
address a1 = ecrecover(hash, _v1, _r1, _s1); address a1 = ecrecover(hash, v1, r1, s1);
require(_v1 == _v2); require(v1 == v2);
require(_r1 == _r2); require(r1 == r2);
require(_s1 == _s2); require(s1 == s2);
address a2 = ecrecover(hash, _v2, _r2, _s2); address a2 = ecrecover(hash, v2, r2, s2);
assert(a1 == a2); assert(a1 == a2);
return a1; return a1;
} }

View File

@ -4,12 +4,12 @@
Mapping Types Mapping Types
============= =============
Mapping types use the syntax ``mapping(_KeyType => _ValueType)`` and variables Mapping types use the syntax ``mapping(KeyType => ValueType)`` and variables
of mapping type are declared using the syntax ``mapping(_KeyType => _ValueType) _VariableName``. of mapping type are declared using the syntax ``mapping(KeyType => ValueType) VariableName``.
The ``_KeyType`` can be any The ``KeyType`` can be any
built-in value type, ``bytes``, ``string``, or any contract or enum type. Other user-defined built-in value type, ``bytes``, ``string``, or any contract or enum type. Other user-defined
or complex types, such as mappings, structs or array types are not allowed. or complex types, such as mappings, structs or array types are not allowed.
``_ValueType`` can be any type, including mappings, arrays and structs. ``ValueType`` can be any type, including mappings, arrays and structs.
You can think of mappings as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_, which are virtually initialised You can think of mappings as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_, which are virtually initialised
such that every possible key exists and is mapped to a value whose such that every possible key exists and is mapped to a value whose
@ -29,10 +29,10 @@ of contract functions that are publicly visible.
These restrictions are also true for arrays and structs that contain mappings. These restrictions are also true for arrays and structs that contain mappings.
You can mark state variables of mapping type as ``public`` and Solidity creates a You can mark state variables of mapping type as ``public`` and Solidity creates a
:ref:`getter <visibility-and-getters>` for you. The ``_KeyType`` becomes a parameter for the getter. :ref:`getter <visibility-and-getters>` for you. The ``KeyType`` becomes a parameter for the getter.
If ``_ValueType`` is a value type or a struct, the getter returns ``_ValueType``. If ``ValueType`` is a value type or a struct, the getter returns ``ValueType``.
If ``_ValueType`` is an array or a mapping, the getter has one parameter for If ``ValueType`` is an array or a mapping, the getter has one parameter for
each ``_KeyType``, recursively. each ``KeyType``, recursively.
In the example below, the ``MappingExample`` contract defines a public ``balances`` In the example below, the ``MappingExample`` contract defines a public ``balances``
mapping, with the key type an ``address``, and a value type a ``uint``, mapping mapping, with the key type an ``address``, and a value type a ``uint``, mapping

View File

@ -511,21 +511,21 @@ Array slices are useful to ABI-decode secondary data passed in function paramete
/// @dev Address of the client contract managed by proxy i.e., this contract /// @dev Address of the client contract managed by proxy i.e., this contract
address client; address client;
constructor(address _client) { constructor(address client_) {
client = _client; client = client_;
} }
/// Forward call to "setOwner(address)" that is implemented by client /// Forward call to "setOwner(address)" that is implemented by client
/// after doing basic validation on the address argument. /// after doing basic validation on the address argument.
function forward(bytes calldata _payload) external { function forward(bytes calldata payload) external {
bytes4 sig = bytes4(_payload[:4]); bytes4 sig = bytes4(payload[:4]);
// Due to truncating behaviour, bytes4(_payload) performs identically. // Due to truncating behaviour, bytes4(payload) performs identically.
// bytes4 sig = bytes4(_payload); // bytes4 sig = bytes4(payload);
if (sig == bytes4(keccak256("setOwner(address)"))) { if (sig == bytes4(keccak256("setOwner(address)"))) {
address owner = abi.decode(_payload[4:], (address)); address owner = abi.decode(payload[4:], (address));
require(owner != address(0), "Address of owner cannot be zero."); require(owner != address(0), "Address of owner cannot be zero.");
} }
(bool status,) = client.delegatecall(_payload); (bool status,) = client.delegatecall(payload);
require(status, "Forwarded call failed."); require(status, "Forwarded call failed.");
} }
} }