Compare commits

...

10 Commits

Author SHA1 Message Date
0457042d93 4.8.1 2023-01-13 15:34:06 -03:00
1dfccff485 Add docs on non-stability of internal function use (#3952)
(cherry picked from commit 717fbc45cb)
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
2023-01-13 11:18:52 +01:00
472b996355 Add explicit permissions to docs workflow
(cherry picked from commit ac30219a6a)
2023-01-12 21:07:54 -03:00
cd50a86a90 Use a staticcall to fetch ERC20.decimals in ERC4626 (#3943)
Co-authored-by: Francisco <frangio.1@gmail.com>
(cherry picked from commit 6b17b33430)
Signed-off-by: Hadrien Croubois <hadrien.croubois@gmail.com>
2023-01-12 17:13:13 +01:00
873a01b220 Fix governance tutorial contract (#3948)
Co-authored-by: Francisco Giordano <frangio.1@gmail.com>
Co-authored-by: Hadrien Croubois <hadrien.croubois@gmail.com>
(cherry picked from commit 5dbde1a5c9)
2023-01-12 10:44:02 -03:00
011a0fb862 Add documentation about the security of overrides (#3725)
(cherry picked from commit e2362ce74f)
2023-01-10 12:41:57 -03:00
4e5b11919e Improve documentation of Initializable getters (#3861)
Co-authored-by: Ernesto García <ernestognw@gmail.com>
(cherry picked from commit 3d7a93876a)
2022-12-07 09:33:25 -05:00
3e97221049 Add ERC-4626 Upgrade Note (#3849)
(cherry picked from commit c30fad9955)
2022-12-02 17:11:02 -03:00
fad1172e63 Add Ownable2Step to the docs (#3836)
Co-authored-by: Francisco <fg@frang.io>
(cherry picked from commit 24d1bb668a)
2022-12-01 10:35:17 -03:00
53eb531255 Improve some NatSpec (#3809)
Co-authored-by: JulissaDantes <julissadcj@gmail.com>
(cherry picked from commit 8f8fd84f1e)
2022-11-25 13:11:43 -03:00
13 changed files with 78 additions and 40 deletions

View File

@ -4,6 +4,9 @@ on:
push:
branches: [release-v*]
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest

View File

@ -1,5 +1,9 @@
# Changelog
## 4.8.1 (2023-01-13)
* `ERC4626`: Use staticcall instead of call when fetching underlying ERC-20 decimals. ([#3943](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3943))
## 4.8.0 (2022-11-08)
* `TimelockController`: Added a new `admin` constructor parameter that is assigned the admin role instead of the deployer account. ([#3722](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/3722))
@ -75,6 +79,18 @@ ERC-721 integrators that interpret contract state from events should make sure t
With the new `ERC721Consecutive` extension, the internal workings of `ERC721` are slightly changed. Custom extensions to ERC721 should be reviewed to ensure they remain correct. The internal functions that should be considered are `_ownerOf` (new), `_beforeTokenTransfer`, and `_afterTokenTransfer`.
### ERC-4626 Upgrade Note
Existing `ERC4626` contracts that are upgraded to 4.8 must initialize a new variable that holds the vault token decimals. The recommended way to do this is to use a [reinitializer]:
[reinitializer]: https://docs.openzeppelin.com/contracts/4.x/api/proxy#Initializable-reinitializer-uint8-
```solidity
function migrateToV48() public reinitializer(2) {
__ERC4626_init(IERC20Upgradeable(asset()));
}
```
## 4.7.3
### Breaking changes

View File

@ -12,6 +12,8 @@ This directory provides ways to restrict who can access the functions of a contr
{{Ownable}}
{{Ownable2Step}}
{{IAccessControl}}
{{AccessControl}}

View File

@ -1,7 +1,7 @@
{
"name": "@openzeppelin/contracts",
"description": "Secure Smart Contract library for Solidity",
"version": "4.8.0",
"version": "4.8.1",
"files": [
"**/*.sol",
"/build/contracts/*.json",

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol)
// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
@ -150,14 +150,14 @@ abstract contract Initializable {
}
/**
* @dev Internal function that returns the initialized version. Returns `_initialized`
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Internal function that returns the initialized version. Returns `_initializing`
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/ERC20Votes.sol)
// OpenZeppelin Contracts (last updated v4.8.1) (token/ERC20/extensions/ERC20Votes.sol)
pragma solidity ^0.8.0;
@ -263,6 +263,9 @@ abstract contract ERC20Votes is IVotes, ERC20Permit {
return a - b;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint[] storage ckpts, uint256 pos) private pure returns (Checkpoint storage result) {
assembly {
mstore(0, ckpts.slot)

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/extensions/ERC4626.sol)
// OpenZeppelin Contracts (last updated v4.8.1) (token/ERC20/extensions/ERC4626.sol)
pragma solidity ^0.8.0;
@ -17,8 +17,12 @@ import "../../../utils/math/Math.sol";
* the ERC20 standard. Any additional extensions included along it would affect the "shares" token represented by this
* contract and not the "assets" token which is an independent contract.
*
* CAUTION: Deposits and withdrawals may incur unexpected slippage. Users should verify that the amount received of
* shares or assets is as expected. EOAs should operate through a wrapper that performs these checks such as
* CAUTION: When the vault is empty or nearly empty, deposits are at high risk of being stolen through frontrunning with
* a "donation" to the vault that inflates the price of a share. This is variously known as a donation or inflation
* attack and is essentially a problem of slippage. Vault deployers can protect against this attack by making an initial
* deposit of a non-trivial amount of the asset, such that price manipulation becomes infeasible. Withdrawals may
* similarly be affected by slippage. Users can protect against this attack as well unexpected slippage in general by
* verifying the amount received is as expected, using a wrapper that performs these checks such as
* https://github.com/fei-protocol/ERC4626#erc4626router-and-base[ERC4626Router].
*
* _Available since v4.7._
@ -41,8 +45,8 @@ abstract contract ERC4626 is ERC20, IERC4626 {
/**
* @dev Attempts to fetch the asset decimals. A return value of false indicates that the attempt failed in some way.
*/
function _tryGetAssetDecimals(IERC20 asset_) private returns (bool, uint8) {
(bool success, bytes memory encodedDecimals) = address(asset_).call(
function _tryGetAssetDecimals(IERC20 asset_) private view returns (bool, uint8) {
(bool success, bytes memory encodedDecimals) = address(asset_).staticcall(
abi.encodeWithSelector(IERC20Metadata.decimals.selector)
);
if (success && encodedDecimals.length >= 32) {
@ -134,7 +138,11 @@ abstract contract ERC4626 is ERC20, IERC4626 {
return shares;
}
/** @dev See {IERC4626-mint}. */
/** @dev See {IERC4626-mint}.
*
* As opposed to {deposit}, minting is allowed even if the vault is in a state where the price of a share is zero.
* In this case, the shares will be minted without requiring any assets to be deposited.
*/
function mint(uint256 shares, address receiver) public virtual override returns (uint256) {
require(shares <= maxMint(receiver), "ERC4626: mint more than max");
@ -267,6 +275,9 @@ abstract contract ERC4626 is ERC20, IERC4626 {
emit Withdraw(caller, receiver, owner, assets, shares);
}
/**
* @dev Checks if vault is "healthy" in the sense of having assets backing the circulating shares.
*/
function _isVaultCollateralized() private view returns (bool) {
return totalAssets() > 0 || totalSupply() == 0;
}

View File

@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Checkpoints.sol)
// OpenZeppelin Contracts (last updated v4.8.1) (utils/Checkpoints.sol)
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.
pragma solidity ^0.8.0;
@ -28,7 +28,8 @@ library Checkpoints {
/**
* @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
* before it is returned, or zero otherwise.
* before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the
* block, the requested block number must be in the past, excluding the current block.
*/
function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
require(blockNumber < block.number, "Checkpoints: block not yet mined");
@ -205,6 +206,9 @@ library Checkpoints {
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {
assembly {
mstore(0, self.slot)
@ -366,6 +370,9 @@ library Checkpoints {
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint224[] storage self, uint256 pos)
private
pure
@ -531,6 +538,9 @@ library Checkpoints {
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint160[] storage self, uint256 pos)
private
pure

View File

@ -122,3 +122,10 @@ contract MyToken is ERC20 {
```
That's it! Enjoy simpler code using hooks!
== Security
The maintainers of OpenZeppelin Contracts are mainly concerned with the correctness and security of the code as published in the library, and the combinations of base contracts with the official extensions from the library.
Custom overrides, and those of hooks in particular, may break some important assumptions and introduce vulnerabilities in otherwise secure code. While we try to ensure the contracts remain secure in the face of a wide range of potential customizations, this is done in a best-effort manner. While we try to document all important assumptions, this should not be relied upon. Custom overrides should be carefully reviewed and checked against the source code of the contract they are customizing so as to fully understand their impact and guarantee their security.
The way functions interact internally should not be assumed to stay stable across releases of the library. For example, a function that is used in one context in a particular release may not be used in the same context in the next release. Contracts that override functions should revalidate their assumptions when updating the version of OpenZeppelin Contracts they are built on.

View File

@ -145,11 +145,11 @@ We can optionally set a proposal threshold as well. This restricts proposal crea
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "./governance/Governor.sol";
import "./governance/compatibility/GovernorCompatibilityBravo.sol";
import "./governance/extensions/GovernorVotes.sol";
import "./governance/extensions/GovernorVotesQuorumFraction.sol";
import "./governance/extensions/GovernorTimelockControl.sol";
import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/compatibility/GovernorCompatibilityBravo.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
contract MyGovernor is Governor, GovernorCompatibilityBravo, GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl {
constructor(IVotes _token, TimelockController _timelock)
@ -173,24 +173,6 @@ contract MyGovernor is Governor, GovernorCompatibilityBravo, GovernorVotes, Gove
// The functions below are overrides required by Solidity.
function quorum(uint256 blockNumber)
public
view
override(IGovernor, GovernorVotesQuorumFraction)
returns (uint256)
{
return super.quorum(blockNumber);
}
function getVotes(address account, uint256 blockNumber)
public
view
override(IGovernor, GovernorVotes)
returns (uint256)
{
return super.getVotes(account, blockNumber);
}
function state(uint256 proposalId)
public
view

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "openzeppelin-solidity",
"version": "4.8.0",
"version": "4.8.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "openzeppelin-solidity",
"version": "4.8.0",
"version": "4.8.1",
"license": "MIT",
"bin": {
"openzeppelin-contracts-migrate-imports": "scripts/migrate-imports.js"

View File

@ -1,7 +1,7 @@
{
"name": "openzeppelin-solidity",
"description": "Secure Smart Contract library for Solidity",
"version": "4.8.0",
"version": "4.8.1",
"files": [
"/contracts/**/*.sol",
"/build/contracts/*.json",

View File

@ -67,7 +67,8 @@ function upperLookup(${opts.historyTypeName} storage self, ${opts.keyTypeName} k
const legacyOperations = opts => `\
/**
* @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
* before it is returned, or zero otherwise.
* before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the
* block, the requested block number must be in the past, excluding the current block.
*/
function getAtBlock(${opts.historyTypeName} storage self, uint256 blockNumber) internal view returns (uint256) {
require(blockNumber < block.number, "Checkpoints: block not yet mined");
@ -246,6 +247,9 @@ function _lowerBinaryLookup(
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(${opts.checkpointTypeName}[] storage self, uint256 pos)
private
pure