diff --git a/script/DeployProxy.s.sol b/script/DeployProxy.s.sol index 2efd61e..c168905 100644 --- a/script/DeployProxy.s.sol +++ b/script/DeployProxy.s.sol @@ -20,10 +20,7 @@ contract DeployUUPSProxy is Script { console.log("TokenFactoryV1 deployed to:", address(_implementation)); // Encode the initializer function call - bytes memory data = abi.encodeCall( - _implementation.initialize, - deployerAddress - ); + bytes memory data = abi.encodeCall(_implementation.initialize, deployerAddress); // Deploy the proxy contract with the implementation address and initializer ERC1967Proxy proxy = new ERC1967Proxy(address(_implementation), data); diff --git a/script/TokenFactoryV2.s.sol b/script/TokenFactoryV2.s.sol index 88b4a49..0fc5497 100644 --- a/script/TokenFactoryV2.s.sol +++ b/script/TokenFactoryV2.s.sol @@ -19,22 +19,11 @@ contract TokenFactoryV2Script is Script { console.log("Deploying contracts with the account:", deployerAddress); vm.startBroadcast(deployerPrivateKey); - Upgrades.upgradeProxy( - address(proxy), - "TokenFactoryV2.sol:TokenFactoryV2", - "", - deployerAddress - ); - (bool successful, ) = address(proxy).call( - abi.encodeWithSelector( - TokenFactoryV2.setTokenAddress.selector, - address(erc20Token) - ) - ); + Upgrades.upgradeProxy(address(proxy), "TokenFactoryV2.sol:TokenFactoryV2", "", deployerAddress); + (bool successful,) = + address(proxy).call(abi.encodeWithSelector(TokenFactoryV2.setTokenAddress.selector, address(erc20Token))); console.log("setTokenAddress success:", successful); - // console.log("TokenFactoryV1 deployed to:", address(factoryv2)); - vm.stopBroadcast(); } } diff --git a/src/ERC20Token.sol b/src/ERC20Token.sol index bbb7af7..0706717 100644 --- a/src/ERC20Token.sol +++ b/src/ERC20Token.sol @@ -21,8 +21,8 @@ contract ERC20Token is ERC20PermitUpgradeable, ERC20VotesUpgradeable { - uint public totalSupplyToken; - uint public perMint; + uint256 public totalSupplyToken; + uint256 public perMint; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { @@ -37,12 +37,10 @@ contract ERC20Token is * @param _perMint perMint 用来控制每次发行的数量 * */ - function initialize( - address initialOwner, - string memory _symbol, - uint _totalSupply, - uint _perMint - ) public initializer { + function initialize(address initialOwner, string memory _symbol, uint256 _totalSupply, uint256 _perMint) + public + initializer + { __ERC20_init("ERC20Token", _symbol); __ERC20Burnable_init(); __ERC20Pausable_init(); @@ -62,40 +60,22 @@ contract ERC20Token is } function mint(address to) public { - uint currentSupply = totalSupply(); // 获取当前代币供应量 + uint256 currentSupply = totalSupply(); // 获取当前代币供应量 // 确保铸造后总供应量不超过最大供应量 - require( - currentSupply + perMint <= totalSupplyToken, - "Exceeds max total supply" - ); + require(currentSupply + perMint <= totalSupplyToken, "Exceeds max total supply"); _mint(to, perMint); } // The following functions are overrides required by Solidity. - function _update( - address from, - address to, - uint256 value - ) + function _update(address from, address to, uint256 value) internal - override( - ERC20Upgradeable, - ERC20PausableUpgradeable, - ERC20VotesUpgradeable - ) + override(ERC20Upgradeable, ERC20PausableUpgradeable, ERC20VotesUpgradeable) { super._update(from, to, value); } - function nonces( - address owner - ) - public - view - override(ERC20PermitUpgradeable, NoncesUpgradeable) - returns (uint256) - { + function nonces(address owner) public view override(ERC20PermitUpgradeable, NoncesUpgradeable) returns (uint256) { return super.nonces(owner); } } diff --git a/src/TokenFactoryV1.sol b/src/TokenFactoryV1.sol index e978707..9f1f512 100644 --- a/src/TokenFactoryV1.sol +++ b/src/TokenFactoryV1.sol @@ -23,9 +23,7 @@ contract TokenFactoryV1 is Initializable, OwnableUpgradeable, UUPSUpgradeable { __UUPSUpgradeable_init(); } - function _authorizeUpgrade( - address newImplementation - ) internal override onlyOwner {} + function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} /** * 该方法用来创建 ERC20 token,(模拟铭文的 deploy) @@ -37,11 +35,7 @@ contract TokenFactoryV1 is Initializable, OwnableUpgradeable, UUPSUpgradeable { * deployInscription(string symbol, uint totalSupply, uint perMint) * */ - function deployInscription( - string memory symbol, - uint totalSupply, - uint perMint - ) public { + function deployInscription(string memory symbol, uint256 totalSupply, uint256 perMint) public { myToken = new ERC20Token(); myToken.initialize(msg.sender, symbol, totalSupply, perMint); console.log("deployInscription newToken: ", address(myToken)); @@ -61,7 +55,7 @@ contract TokenFactoryV1 is Initializable, OwnableUpgradeable, UUPSUpgradeable { token.mint(msg.sender); // Assuming ERC20Token has a mint function with (address, uint256) parameters } - function size() public view returns (uint) { + function size() public view returns (uint256) { return deployedTokens.length; } } diff --git a/src/TokenFactoryV2.sol b/src/TokenFactoryV2.sol index d3d3822..14378db 100644 --- a/src/TokenFactoryV2.sol +++ b/src/TokenFactoryV2.sol @@ -14,21 +14,13 @@ import "./ERC20Token.sol"; contract TokenFactoryV2 is Initializable, OwnableUpgradeable, UUPSUpgradeable { ERC20Token myToken; address[] public deployedTokens; - mapping(address => uint) public tokenPrices; - mapping(address => uint) public tokenperMint; + mapping(address => uint256) public tokenPrices; + mapping(address => uint256) public tokenperMint; mapping(address => address) public tokenDeployUser; - event deployInscriptionEvent( - address indexed tokenAddress, - address indexed userAddress, - uint indexed price - ); + event deployInscriptionEvent(address indexed tokenAddress, address indexed userAddress, uint256 indexed price); - event mintInscriptionEvent( - address indexed tokenAddress, - address indexed userAddress, - uint indexed amount - ); + event mintInscriptionEvent(address indexed tokenAddress, address indexed userAddress, uint256 indexed amount); /// @custom:oz-upgrades-unsafe-allow constructor constructor() { @@ -44,9 +36,7 @@ contract TokenFactoryV2 is Initializable, OwnableUpgradeable, UUPSUpgradeable { myToken = ERC20Token(_tokenAddress); } - function _authorizeUpgrade( - address newImplementation - ) internal override onlyOwner {} + function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} /** * 部署新的 ERC20 代币合约 @@ -55,32 +45,19 @@ contract TokenFactoryV2 is Initializable, OwnableUpgradeable, UUPSUpgradeable { * @param perMint perMint 用来控制每次发行的数量,用于控制mintInscription函数每次发行的数量 * @param price 每个代币的价格 price 表示发行每个 token 需要支付的费用 */ - function deployInscription( - string memory symbol, - uint totalSupply, - uint perMint, - uint price - ) public { + function deployInscription(string memory symbol, uint256 totalSupply, uint256 perMint, uint256 price) public { require(bytes(symbol).length > 0, "Symbol cannot be empty"); require(totalSupply > 0, "Total supply must be greater than zero"); require(perMint > 0, "Per mint must be greater than zero"); require(price > 0, "Price must be greater than zero"); - require( - address(myToken) != address(0), - "Implementation address is not set" - ); + require(address(myToken) != address(0), "Implementation address is not set"); console.log("deployInscription msg.sender, address:", msg.sender); // 使用 Clones 库创建最小代理合约实例 address newToken = Clones.clone(address(myToken)); - ERC20Token(newToken).initialize( - msg.sender, - symbol, - totalSupply, - perMint - ); + ERC20Token(newToken).initialize(msg.sender, symbol, totalSupply, perMint); deployedTokens.push(newToken); tokenPrices[newToken] = price; @@ -95,13 +72,13 @@ contract TokenFactoryV2 is Initializable, OwnableUpgradeable, UUPSUpgradeable { */ function mintInscription(address tokenAddr) public payable { ERC20Token token = ERC20Token(tokenAddr); - uint price = tokenPrices[tokenAddr]; - uint perMint = tokenperMint[tokenAddr]; + uint256 price = tokenPrices[tokenAddr]; + uint256 perMint = tokenperMint[tokenAddr]; address userAddr = tokenDeployUser[tokenAddr]; require(msg.value >= (price * perMint), "Incorrect payment"); token.mint(msg.sender); // 使用 call 方法转账,以避免 gas 限制问题 payable(userAddr).transfer(msg.value); - (bool success, ) = userAddr.call{value: msg.value}(""); + (bool success,) = userAddr.call{value: msg.value}(""); require(success, "Transfer failed."); emit mintInscriptionEvent(tokenAddr, userAddr, msg.value); @@ -111,12 +88,12 @@ contract TokenFactoryV2 is Initializable, OwnableUpgradeable, UUPSUpgradeable { * 提取合约余额 */ function withdraw() external onlyOwner { - uint balance = address(this).balance; + uint256 balance = address(this).balance; require(balance > 0, "No funds to withdraw"); payable(owner()).transfer(balance); } - function size() public view returns (uint) { + function size() public view returns (uint256) { return deployedTokens.length; } } diff --git a/test/ERC20TokenTest.sol b/test/ERC20TokenTest.sol index 4d8a82b..a313bf9 100644 --- a/test/ERC20TokenTest.sol +++ b/test/ERC20TokenTest.sol @@ -14,8 +14,8 @@ contract ERC20TokenTest is Test { Account public newOwner = makeAccount("newOwner"); Account public user = makeAccount("user"); string public symbol = "ETK"; - uint public totalSupply = 1_000_000 ether; - uint public perMint = 10 ether; + uint256 public totalSupply = 1_000_000 ether; + uint256 public perMint = 10 ether; function setUp() public { // 部署实现 @@ -23,10 +23,7 @@ contract ERC20TokenTest is Test { // Deploy the proxy and initialize the contract through the proxy proxy = new ERC1967Proxy( address(implementation), - abi.encodeCall( - implementation.initialize, - (owner.addr, symbol, totalSupply, perMint) - ) + abi.encodeCall(implementation.initialize, (owner.addr, symbol, totalSupply, perMint)) ); // 用代理关联 MyToken 接口 myToken = ERC20Token(address(proxy)); diff --git a/test/TokenFactoryV1Test.sol b/test/TokenFactoryV1Test.sol index 0deb3f4..aff5b99 100644 --- a/test/TokenFactoryV1Test.sol +++ b/test/TokenFactoryV1Test.sol @@ -21,9 +21,9 @@ contract TokenFactoryV1Test is Test { Account public user = makeAccount("user"); string public symbol = "ETK"; - uint public totalSupply = 1_000_000 ether; - uint public perMint = 10 ether; - uint public price = 10 ** 16; // 0.01 ETH in wei + uint256 public totalSupply = 1_000_000 ether; + uint256 public perMint = 10 ether; + uint256 public price = 10 ** 16; // 0.01 ETH in wei function setUp() public { myToken = new ERC20Token(); @@ -31,10 +31,7 @@ contract TokenFactoryV1Test is Test { // 部署实现 TokenFactoryV1 implementation = new TokenFactoryV1(); // Deploy the proxy and initialize the contract through the proxy - proxy = new ERC1967Proxy( - address(implementation), - abi.encodeCall(implementation.initialize, owner.addr) - ); + proxy = new ERC1967Proxy(address(implementation), abi.encodeCall(implementation.initialize, owner.addr)); // 用代理关联 TokenFactoryV1 接口 factoryv1 = TokenFactoryV1(address(proxy)); // Emit the owner address for debugging purposes @@ -62,9 +59,7 @@ contract TokenFactoryV1Test is Test { assertEq(deployedToken.owner(), owner.addr); } - function testTokenFactoryV1PermissionsDeployInscriptionFunctionality() - public - { + function testTokenFactoryV1PermissionsDeployInscriptionFunctionality() public { vm.startPrank(user.addr); factoryv1.deployInscription(symbol, totalSupply, perMint); @@ -102,9 +97,7 @@ contract TokenFactoryV1Test is Test { vm.stopPrank(); } - function testTokenFactoryV1PermissionsMintInscriptionFunctionality() - public - { + function testTokenFactoryV1PermissionsMintInscriptionFunctionality() public { vm.startPrank(user.addr); factoryv1.deployInscription(symbol, totalSupply, perMint); @@ -114,10 +107,7 @@ contract TokenFactoryV1Test is Test { deployedToken = ERC20Token(deployedTokenAddress); factoryv1.mintInscription(deployedTokenAddress); - assertEq( - ERC20Token(deployedTokenAddress).balanceOf(user.addr), - 10 ether - ); + assertEq(ERC20Token(deployedTokenAddress).balanceOf(user.addr), 10 ether); assertEq(deployedToken.balanceOf(user.addr), 10 ether); assertEq(deployedToken.totalSupply(), 10 ether); assertEq(deployedToken.totalSupplyToken(), totalSupply); @@ -126,12 +116,7 @@ contract TokenFactoryV1Test is Test { // 测试升级 function testUpgradeability() public { - Upgrades.upgradeProxy( - address(proxy), - "TokenFactoryV2.sol:TokenFactoryV2", - "", - owner.addr - ); + Upgrades.upgradeProxy(address(proxy), "TokenFactoryV2.sol:TokenFactoryV2", "", owner.addr); } function testERC20Functionality() public { @@ -149,77 +134,49 @@ contract TokenFactoryV1Test is Test { testERC20Functionality(); vm.prank(owner.addr); // TokenFactoryV2 factoryV2 = new TokenFactoryV2(); - assertEq(deployedToken.balanceOf(user.addr), perMint); /// + assertEq(deployedToken.balanceOf(user.addr), perMint); + /// // 1. 升级代理合约 - Upgrades.upgradeProxy( - address(proxy), - "TokenFactoryV2.sol:TokenFactoryV2", - "", - owner.addr - ); + Upgrades.upgradeProxy(address(proxy), "TokenFactoryV2.sol:TokenFactoryV2", "", owner.addr); // TokenFactoryV2 factoryV2 = TokenFactoryV2(address(proxy)); factoryv2 = TokenFactoryV2(address(proxy)); console.log("Verify upgradeability"); vm.prank(owner.addr); - (bool s, ) = address(proxy).call( - abi.encodeWithSignature( - "setTokenAddress(address)", - address(myToken) - ) - ); + (bool s,) = address(proxy).call(abi.encodeWithSignature("setTokenAddress(address)", address(myToken))); require(s); // 验证新的功能 // 2. deployInscription vm.startPrank(user.addr); deal(user.addr, price * perMint); - (bool success, ) = address(proxy).call( - abi.encodeWithSelector( - factoryv2.deployInscription.selector, - symbol, - totalSupply, - perMint, - price - ) + (bool success,) = address(proxy).call( + abi.encodeWithSelector(factoryv2.deployInscription.selector, symbol, totalSupply, perMint, price) ); assertEq(success, true); - (bool su, bytes memory deployedTokenAddressBytes) = address(proxy).call( - abi.encodeWithSelector(factoryv2.deployedTokens.selector, 0) - ); + (bool su, bytes memory deployedTokenAddressBytes) = + address(proxy).call(abi.encodeWithSelector(factoryv2.deployedTokens.selector, 0)); assertEq(su, true); - address deployedTokenAddress = abi.decode( - deployedTokenAddressBytes, - (address) - ); + address deployedTokenAddress = abi.decode(deployedTokenAddressBytes, (address)); console.log("deployedTokenAddress", deployedTokenAddress); - (bool sus, bytes memory deployedTokensLengthBytes) = address(proxy) - .call(abi.encodeWithSelector(factoryv2.size.selector)); + (bool sus, bytes memory deployedTokensLengthBytes) = + address(proxy).call(abi.encodeWithSelector(factoryv2.size.selector)); assertEq(sus, true); - uint256 deployedTokensLength = abi.decode( - deployedTokensLengthBytes, - (uint256) - ); + uint256 deployedTokensLength = abi.decode(deployedTokensLengthBytes, (uint256)); console.log("deployedTokensLength", deployedTokensLength); assertEq(deployedTokensLength, 2); - (bool su2, bytes memory deployedTokenAddressBytes2) = address(proxy) - .call(abi.encodeWithSelector(factoryv2.deployedTokens.selector, 1)); + (bool su2, bytes memory deployedTokenAddressBytes2) = + address(proxy).call(abi.encodeWithSelector(factoryv2.deployedTokens.selector, 1)); assertEq(su2, true); - address deployedTokenAddress2 = abi.decode( - deployedTokenAddressBytes2, - (address) - ); + address deployedTokenAddress2 = abi.decode(deployedTokenAddressBytes2, (address)); assertNotEq(deployedTokenAddress, deployedTokenAddress2); // 3. mintInscription deployedToken = ERC20Token(deployedTokenAddress2); - (bool mintSuccess, ) = address(proxy).call{value: price * perMint}( - abi.encodeWithSignature( - "mintInscription(address)", - deployedTokenAddress2 - ) + (bool mintSuccess,) = address(proxy).call{value: price * perMint}( + abi.encodeWithSignature("mintInscription(address)", deployedTokenAddress2) ); require(mintSuccess, "Minting of token failed"); diff --git a/test/TokenFactoryV2Test.sol b/test/TokenFactoryV2Test.sol index 8494fb0..7324eb6 100644 --- a/test/TokenFactoryV2Test.sol +++ b/test/TokenFactoryV2Test.sol @@ -21,9 +21,9 @@ contract CounterTest is Test { Account public user = makeAccount("user"); string public symbol = "ETK"; - uint public totalSupply = 1_000_000 ether; - uint public perMint = 10 ether; - uint public price = 10 ** 16; // 0.01 ETH in wei + uint256 public totalSupply = 1_000_000 ether; + uint256 public perMint = 10 ether; + uint256 public price = 10 ** 16; // 0.01 ETH in wei address public tokenAddr; function setUp() public { @@ -32,21 +32,14 @@ contract CounterTest is Test { TokenFactoryV2 implementationV2 = new TokenFactoryV2(); vm.prank(owner.addr); - proxy = new ERC1967Proxy( - address(implementationV2), - abi.encodeCall(implementationV2.initialize, (owner.addr)) - ); + proxy = new ERC1967Proxy(address(implementationV2), abi.encodeCall(implementationV2.initialize, (owner.addr))); // 用代理关联 TokenFactoryV2 接口 factoryv2 = TokenFactoryV2(address(proxy)); vm.prank(owner.addr); - (bool success, ) = address(proxy).call( - abi.encodeWithSelector( - factoryv2.setTokenAddress.selector, - address(myToken) - ) - ); + (bool success,) = + address(proxy).call(abi.encodeWithSelector(factoryv2.setTokenAddress.selector, address(myToken))); require(success); @@ -77,9 +70,7 @@ contract CounterTest is Test { vm.stopPrank(); } - function testTokenFactoryV2PermissionsDeployInscriptionFunctionality() - public - { + function testTokenFactoryV2PermissionsDeployInscriptionFunctionality() public { vm.startPrank(user.addr); factoryv2.deployInscription(symbol, totalSupply, perMint, price); @@ -120,9 +111,7 @@ contract CounterTest is Test { vm.stopPrank(); } - function testTokenFactoryV2PermissionsMintInscriptionFunctionality() - public - { + function testTokenFactoryV2PermissionsMintInscriptionFunctionality() public { vm.startPrank(user.addr); factoryv2.deployInscription(symbol, totalSupply, perMint, price);