Michael.W基于Foundry精读Openzeppelin第41期——ERC20Capped.sol
- 0. 版本
- 0.1 ERC20Capped.sol
- 1. 目标合约
- 2. 代码精读
- 2.1 constructor() && cap()
- 2.2 _mint(address account, uint256 amount)
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_) {// 要求设置的发行量上限大于0require(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 constructorvm.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神。
以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。
同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下!
如果需要转发,麻烦注明作者。十分感谢!
公众号名称:后现代泼痞浪漫主义奠基人