ERC20Capped库是ERC20的拓展。该库设置了ERC20发行量的上限。
[openzeppelin]:v4.8.3,[forge-std]:v1.5.6
ERC20Capped库是ERC20的拓展。该库设置了ERC20发行量的上限。
继承ERC20Capped合约:
// 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测试合约:
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);
}
}
为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神。 以下是我个人的公众号,如果有技术问题可以关注我的公众号来跟我交流。 同时我也会在这个公众号上每周更新我的原创文章,喜欢的小伙伴或者老伙计可以支持一下! 如果需要转发,麻烦注明作者。十分感谢!
公众号名称:后现代泼痞浪漫主义奠基人
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!