推荐 :https://wizard.openzeppelin.com/

basic erc20

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
␊
contract MyToken is ERC20 {␊
    constructor() ERC20("MyToken", "MTK") {}␊
}␊
`

erc20 with snapshots

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol";␊
import "@openzeppelin/contracts/access/Ownable.sol";␊
␊
contract MyToken is ERC20, ERC20Snapshot, Ownable {␊
    constructor() ERC20("MyToken", "MTK") {}␊
␊
    function snapshot() public onlyOwner {␊
        _snapshot();␊
    }␊
␊
    // The following functions are overrides required by Solidity.␊
␊
    function _beforeTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        override(ERC20, ERC20Snapshot)␊
    {␊
        super._beforeTokenTransfer(from, to, amount);␊
    }␊
}␊
`

erc20 burnable

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";␊
␊
contract MyToken is ERC20, ERC20Burnable {␊
    constructor() ERC20("MyToken", "MTK") {}␊
}␊
`

erc20 burnable with snapshots

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol";␊
import "@openzeppelin/contracts/access/Ownable.sol";␊
␊
contract MyToken is ERC20, ERC20Burnable, ERC20Snapshot, Ownable {␊
    constructor() ERC20("MyToken", "MTK") {}␊
␊
    function snapshot() public onlyOwner {␊
        _snapshot();␊
    }␊
␊
    // The following functions are overrides required by Solidity.␊
␊
    function _beforeTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        override(ERC20, ERC20Snapshot)␊
    {␊
        super._beforeTokenTransfer(from, to, amount);␊
    }␊
}␊
`

erc20 pausable

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/security/Pausable.sol";␊
import "@openzeppelin/contracts/access/Ownable.sol";␊
␊
contract MyToken is ERC20, Pausable, Ownable {␊
    constructor() ERC20("MyToken", "MTK") {}␊
␊
    function pause() public onlyOwner {␊
        _pause();␊
    }␊
␊
    function unpause() public onlyOwner {␊
        _unpause();␊
    }␊
␊
    function _beforeTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        whenNotPaused␊
        override␊
    {␊
        super._beforeTokenTransfer(from, to, amount);␊
    }␊
}␊
`

erc20 pausable with roles

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/security/Pausable.sol";␊
import "@openzeppelin/contracts/access/AccessControl.sol";␊
␊
contract MyToken is ERC20, Pausable, AccessControl {␊
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");␊
␊
    constructor() ERC20("MyToken", "MTK") {␊
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);␊
        _setupRole(PAUSER_ROLE, msg.sender);␊
    }␊
␊
    function pause() public onlyRole(PAUSER_ROLE) {␊
        _pause();␊
    }␊
␊
    function unpause() public onlyRole(PAUSER_ROLE) {␊
        _unpause();␊
    }␊
␊
    function _beforeTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        whenNotPaused␊
        override␊
    {␊
        super._beforeTokenTransfer(from, to, amount);␊
    }␊
}␊
`

erc20 burnable pausable

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";␊
import "@openzeppelin/contracts/security/Pausable.sol";␊
import "@openzeppelin/contracts/access/Ownable.sol";␊
␊
contract MyToken is ERC20, ERC20Burnable, Pausable, Ownable {␊
    constructor() ERC20("MyToken", "MTK") {}␊
␊
    function pause() public onlyOwner {␊
        _pause();␊
    }␊
␊
    function unpause() public onlyOwner {␊
        _unpause();␊
    }␊
␊
    function _beforeTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        whenNotPaused␊
        override␊
    {␊
        super._beforeTokenTransfer(from, to, amount);␊
    }␊
}␊
`

erc20 burnable pausable with snapshots

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol";␊
import "@openzeppelin/contracts/access/Ownable.sol";␊
import "@openzeppelin/contracts/security/Pausable.sol";␊
␊
contract MyToken is ERC20, ERC20Burnable, ERC20Snapshot, Ownable, Pausable {␊
    constructor() ERC20("MyToken", "MTK") {}␊
␊
    function snapshot() public onlyOwner {␊
        _snapshot();␊
    }␊
␊
    function pause() public onlyOwner {␊
        _pause();␊
    }␊
␊
    function unpause() public onlyOwner {␊
        _unpause();␊
    }␊
␊
    function _beforeTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        whenNotPaused␊
        override(ERC20, ERC20Snapshot)␊
    {␊
        super._beforeTokenTransfer(from, to, amount);␊
    }␊
}␊
`

erc20 preminted

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
␊
contract MyToken is ERC20 {␊
    constructor() ERC20("MyToken", "MTK") {␊
        _mint(msg.sender, 1000 * 10 ** decimals());␊
    }␊
}␊
`

erc20 premint of 0

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
␊
contract MyToken is ERC20 {␊
    constructor() ERC20("MyToken", "MTK") {}␊
}␊
`

erc20 mintable

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/access/Ownable.sol";␊
␊
contract MyToken is ERC20, Ownable {␊
    constructor() ERC20("MyToken", "MTK") {}␊
␊
    function mint(address to, uint256 amount) public onlyOwner {␊
        _mint(to, amount);␊
    }␊
}␊
`

erc20 mintable with roles

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/access/AccessControl.sol";␊
␊
contract MyToken is ERC20, AccessControl {␊
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");␊
␊
    constructor() ERC20("MyToken", "MTK") {␊
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);␊
        _setupRole(MINTER_ROLE, msg.sender);␊
    }␊
␊
    function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {␊
        _mint(to, amount);␊
    }␊
}␊
`

erc20 permit

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";␊
␊
contract MyToken is ERC20, ERC20Permit {␊
    constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {}␊
}␊
`

erc20 votes

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";␊
␊
contract MyToken is ERC20, ERC20Permit, ERC20Votes {␊
    constructor() ERC20("MyToken", "MTK") ERC20Permit("MyToken") {}␊
␊
    // The following functions are overrides required by Solidity.␊
␊
    function _afterTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        override(ERC20, ERC20Votes)␊
    {␊
        super._afterTokenTransfer(from, to, amount);␊
    }␊
␊
    function _mint(address to, uint256 amount)␊
        internal␊
        override(ERC20, ERC20Votes)␊
    {␊
        super._mint(to, amount);␊
    }␊
␊
    function _burn(address account, uint256 amount)␊
        internal␊
        override(ERC20, ERC20Votes)␊
    {␊
        super._burn(account, amount);␊
    }␊
}␊
`

erc20 flashmint

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";␊
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20FlashMint.sol";␊
␊
contract MyToken is ERC20, ERC20FlashMint {␊
    constructor() ERC20("MyToken", "MTK") {}␊
}␊
`

erc20 full upgradeable transparent

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊
␊
contract MyToken is Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, ERC20SnapshotUpgradeable, AccessControlUpgradeable, PausableUpgradeable, ERC20PermitUpgradeable, ERC20VotesUpgradeable, ERC20FlashMintUpgradeable {␊
    bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE");␊
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");␊
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");␊
␊
    function initialize() initializer public {␊
        __ERC20_init("MyToken", "MTK");␊
        __ERC20Burnable_init();␊
        __ERC20Snapshot_init();␊
        __AccessControl_init();␊
        __Pausable_init();␊
        __ERC20Permit_init("MyToken");␊
        __ERC20FlashMint_init();␊
␊
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);␊
        _setupRole(SNAPSHOT_ROLE, msg.sender);␊
        _setupRole(PAUSER_ROLE, msg.sender);␊
        _mint(msg.sender, 2000 * 10 ** decimals());␊
        _setupRole(MINTER_ROLE, msg.sender);␊
    }␊
␊
    function snapshot() public onlyRole(SNAPSHOT_ROLE) {␊
        _snapshot();␊
    }␊
␊
    function pause() public onlyRole(PAUSER_ROLE) {␊
        _pause();␊
    }␊
␊
    function unpause() public onlyRole(PAUSER_ROLE) {␊
        _unpause();␊
    }␊
␊
    function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {␊
        _mint(to, amount);␊
    }␊
␊
    function _beforeTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        whenNotPaused␊
        override(ERC20Upgradeable, ERC20SnapshotUpgradeable)␊
    {␊
        super._beforeTokenTransfer(from, to, amount);␊
    }␊
␊
    // The following functions are overrides required by Solidity.␊
␊
    function _afterTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        override(ERC20Upgradeable, ERC20VotesUpgradeable)␊
    {␊
        super._afterTokenTransfer(from, to, amount);␊
    }␊
␊
    function _mint(address to, uint256 amount)␊
        internal␊
        override(ERC20Upgradeable, ERC20VotesUpgradeable)␊
    {␊
        super._mint(to, amount);␊
    }␊
␊
    function _burn(address account, uint256 amount)␊
        internal␊
        override(ERC20Upgradeable, ERC20VotesUpgradeable)␊
    {␊
        super._burn(account, amount);␊
    }␊
}␊
`

erc20 full upgradeable uups

Snapshot 1

`// SPDX-License-Identifier: MIT␊
pragma solidity ^0.8.2;␊
␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20SnapshotUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20FlashMintUpgradeable.sol";␊
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";␊
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";␊
␊
contract MyToken is Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, ERC20SnapshotUpgradeable, AccessControlUpgradeable, PausableUpgradeable, ERC20PermitUpgradeable, ERC20VotesUpgradeable, ERC20FlashMintUpgradeable, UUPSUpgradeable {␊
    bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE");␊
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");␊
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");␊
    bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");␊
␊
    function initialize() initializer public {␊
        __ERC20_init("MyToken", "MTK");␊
        __ERC20Burnable_init();␊
        __ERC20Snapshot_init();␊
        __AccessControl_init();␊
        __Pausable_init();␊
        __ERC20Permit_init("MyToken");␊
        __ERC20FlashMint_init();␊
        __UUPSUpgradeable_init();␊
␊
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);␊
        _setupRole(SNAPSHOT_ROLE, msg.sender);␊
        _setupRole(PAUSER_ROLE, msg.sender);␊
        _mint(msg.sender, 2000 * 10 ** decimals());␊
        _setupRole(MINTER_ROLE, msg.sender);␊
        _setupRole(UPGRADER_ROLE, msg.sender);␊
    }␊
␊
    function snapshot() public onlyRole(SNAPSHOT_ROLE) {␊
        _snapshot();␊
    }␊
␊
    function pause() public onlyRole(PAUSER_ROLE) {␊
        _pause();␊
    }␊
␊
    function unpause() public onlyRole(PAUSER_ROLE) {␊
        _unpause();␊
    }␊
␊
    function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {␊
        _mint(to, amount);␊
    }␊
␊
    function _beforeTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        whenNotPaused␊
        override(ERC20Upgradeable, ERC20SnapshotUpgradeable)␊
    {␊
        super._beforeTokenTransfer(from, to, amount);␊
    }␊
␊
    function _authorizeUpgrade(address newImplementation)␊
        internal␊
        onlyRole(UPGRADER_ROLE)␊
        override␊
    {}␊
␊
    // The following functions are overrides required by Solidity.␊
␊
    function _afterTokenTransfer(address from, address to, uint256 amount)␊
        internal␊
        override(ERC20Upgradeable, ERC20VotesUpgradeable)␊
    {␊
        super._afterTokenTransfer(from, to, amount);␊
    }␊
␊
    function _mint(address to, uint256 amount)␊
        internal␊
        override(ERC20Upgradeable, ERC20VotesUpgradeable)␊
    {␊
        super._mint(to, amount);␊
    }␊
␊
    function _burn(address account, uint256 amount)␊
        internal␊
        override(ERC20Upgradeable, ERC20VotesUpgradeable)␊
    {␊
        super._burn(account, amount);␊
    }␊
}␊
`

转载自:https://github.com/OpenZeppelin/contracts-wizard/blob/0dbf5d669adcdb8e801fbb67a269fc7931613d66/packages/core/src/erc20.test.ts.md