Michael.W基于Foundry精读Openzeppelin第41期——ERC20Capped.sol

  • Michael.W
  • 更新于 2023-12-08 17:49
  • 阅读 1397

ERC20Capped库是ERC20的拓展。该库设置了ERC20发行量的上限。

0. 版本

[openzeppelin]:v4.8.3,[forge-std]:v1.5.6

0.1 ERC20Capped.sol

Github: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.3/contracts/token/ERC20/extensions/ERC20Capped.sol

ERC20Capped库是ERC20的拓展。该库设置了ERC20发行量的上限。

1. 目标合约

继承ERC20Capped合约:

Github: https://github.com/RevelationOfTuring/foundry-openzeppelin-contracts/blob/master/src/token/ERC20/extensions/MockERC20Capped.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Capped.sol";

contract MockERC20Capped is ERC20Capped {
    constructor(string memory name, string memory symbol, uint cap)
    ERC20(name, symbol)
    ERC20Capped(cap){}

    function mint(address account, uint amount) external {
        _mint(account, amount);
    }
}

全部foundry测试合约:

Github: https://github.com/RevelationOfTuring/foundry-openzeppelin-contracts/blob/master/test/token/ERC20/extensions/ERC20Capped.t.sol

2. 代码精读

2.1 constructor() && cap()

  • constructor():初始化函数对发行量上限进行了设置;
  • cap():返回ERC20发行量上限
    // token发行量上限(immutable类型,合约初始化后无法再更改)
    uint256 private immutable _cap;

    constructor(uint256 cap_) {
        // 要求设置的发行量上限大于0
        require(cap_ > 0, "ERC20Capped: cap is 0");
        // 设置上限
        _cap = cap_;
    }

    function cap() public view virtual returns (uint256) {
        // 返回常量_cap的值
        return _cap;
    }

foundry代码验证:

contract ERC20CappedTest is Test {
    MockERC20Capped private _testing = new MockERC20Capped("test name", "test symbol", 100);

    function test_Constructor() external {
        assertEq(_testing.cap(), 100);

        // revert with 0 cap in constructor
        vm.expectRevert("ERC20Capped: cap is 0");
        new MockERC20Capped("test name", "test symbol", 0);
    }
}

2.2 _mint(address account, uint256 amount)

为account地址铸造数量为amount的token。

    function _mint(address account, uint256 amount) internal virtual override {
        // 检查本次mint后的总发行量不得大于发行量上限
        require(ERC20.totalSupply() + amount <= cap(), "ERC20Capped: cap exceeded");
        // 调用ERC20.mint()进行铸造
        super._mint(account, amount);
    }

foundry代码验证:

contract ERC20CappedTest is Test {
    MockERC20Capped private _testing = new MockERC20Capped("test name", "test symbol", 100);
    address private user = address(1);

    function test_Mint() external {
        _testing.mint(user, 100);
        assertEq(_testing.totalSupply(), 100);

        vm.expectRevert("ERC20Capped: cap exceeded");
        _testing.mint(user, 1);
    }
}

ps: 本人热爱图灵,热爱中本聪,热爱V神。 以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。 同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下! 如果需要转发,麻烦注明作者。十分感谢!

1.jpeg

公众号名称:后现代泼痞浪漫主义奠基人

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Michael.W
Michael.W
0x93E7...0000
狂热的区块链爱好者