Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions contracts/token/ERC20/ERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";

/**
* @dev Implementation of the {IERC20} interface.
Expand Down Expand Up @@ -35,7 +36,7 @@ import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors, Initializable {
mapping(address => uint256) private _balances;

mapping(address => mapping(address => uint256)) private _allowances;
Expand All @@ -56,7 +57,11 @@ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
constructor(string memory name_, string memory symbol_) initializer {
initialize(name_, symbol_);
}

function initialize(string memory name_, string memory symbol_) public onlyInitializing {
_name = name_;
_symbol = symbol_;
}
Expand Down
8 changes: 7 additions & 1 deletion contracts/token/ERC20/extensions/ERC20Permit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {ERC20} from "../ERC20.sol";
import {ECDSA} from "../../../utils/cryptography/ECDSA.sol";
import {EIP712} from "../../../utils/cryptography/EIP712.sol";
import {Nonces} from "../../../utils/Nonces.sol";
import {Initializable} from "../../../proxy/utils/Initializable.sol";

/**
* @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
Expand All @@ -19,7 +20,7 @@ import {Nonces} from "../../../utils/Nonces.sol";
*/
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces {
// solhint-disable-next-line var-name-mixedcase
bytes32 private constant _PERMIT_TYPEHASH =
bytes32 internal _PERMIT_TYPEHASH =
keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

/**
Expand All @@ -39,6 +40,11 @@ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces {
*/
constructor(string memory name) EIP712(name, "1") {}

function initialize(string memory name, string memory symbol) public virtual onlyInitializing {
EIP712.initialize(name, "1");
ERC20.initialize(name, symbol);
}

/**
* @dev See {IERC20Permit-permit}.
*/
Expand Down
23 changes: 14 additions & 9 deletions contracts/utils/cryptography/EIP712.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pragma solidity ^0.8.19;
import {MessageHashUtils} from "./MessageHashUtils.sol";
import {ShortStrings, ShortString} from "../ShortStrings.sol";
import {IERC5267} from "../../interfaces/IERC5267.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";

/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
Expand All @@ -31,23 +32,23 @@ import {IERC5267} from "../../interfaces/IERC5267.sol";
*
* @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
*/
abstract contract EIP712 is IERC5267 {
abstract contract EIP712 is IERC5267, Initializable {
using ShortStrings for *;

bytes32 private constant _TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

// Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
// invalidate the cached domain separator if the chain id changes.
bytes32 private immutable _cachedDomainSeparator;
uint256 private immutable _cachedChainId;
address private immutable _cachedThis;
bytes32 private _cachedDomainSeparator;
uint256 private _cachedChainId;
address private _cachedThis;

bytes32 private immutable _hashedName;
bytes32 private immutable _hashedVersion;
bytes32 private _hashedName;
bytes32 private _hashedVersion;

ShortString private immutable _name;
ShortString private immutable _version;
ShortString private _name;
ShortString private _version;
string private _nameFallback;
string private _versionFallback;

Expand All @@ -63,7 +64,11 @@ abstract contract EIP712 is IERC5267 {
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
constructor(string memory name, string memory version) {
constructor(string memory name, string memory version) initializer {
initialize(name, version);
}

function initialize(string memory name, string memory version) public virtual onlyInitializing {
_name = name.toShortStringWithFallback(_nameFallback);
_version = version.toShortStringWithFallback(_versionFallback);
_hashedName = keccak256(bytes(name));
Expand Down
5 changes: 2 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.