From c7ca803c0bbc2a9b8cf41d5f6bc9ee63ec565b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Volpe?= Date: Wed, 23 Jul 2025 16:17:00 -0300 Subject: [PATCH 1/5] first test --- .../test/L2/OptimismMintableERC20.t.sol | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol diff --git a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol new file mode 100644 index 0000000000000..858bba9f52d45 --- /dev/null +++ b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +// Testing utilities +import { CommonTest } from "test/setup/CommonTest.sol"; + +// Target contract +import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; + +contract OptimismMintableERC20_Beenchmark_Test is CommonTest { + // Test token + OptimismMintableERC20 token; + + // Test addresses + address bridge = address(0x1); + address remoteToken = address(0x2); + address recipient1 = address(0x3); + address recipient2 = address(0x4); + address communityFund = address(0x5); + + function setUp() public override { + // Deploy OptimismMintableERC20 token for testing + token = new OptimismMintableERC20( + bridge, + remoteToken, + "Test Token", + "TEST", + 18 + ); + } + + function test_hapyCase() public { + // Existing empty test + } + + function test_creditAndDebitGasFees() public { + // Step 1: Test new version of creditGasFees with arrays + address[] memory recipients = new address[](2); + recipients[0] = recipient1; + recipients[1] = recipient2; + + uint256[] memory amounts = new uint256[](2); + amounts[0] = 100; + amounts[1] = 200; + + // Call creditGasFees as the VM (address 0) + vm.prank(address(0)); + token.creditGasFees(recipients, amounts); + + // Verify balances + assertEq(token.balanceOf(recipient1), 100); + assertEq(token.balanceOf(recipient2), 200); + + // Step 2: Test debitGasFees + vm.prank(address(0)); + token.debitGasFees(recipient1, 50); + + // Verify balance after debit + assertEq(token.balanceOf(recipient1), 50); + + // Step 3: Test legacy version of creditGasFees + address from = address(0x6); + address feeRecipient = address(0x7); + address gatewayFeeRecipient = address(0x8); // unused + uint256 refund = 75; + uint256 tipTxFee = 25; + uint256 gatewayFee = 10; // unused + uint256 baseTxFee = 30; + + vm.prank(address(0)); + token.creditGasFees( + from, + feeRecipient, + gatewayFeeRecipient, + communityFund, + refund, + tipTxFee, + gatewayFee, + baseTxFee + ); + + // Verify balances after legacy creditGasFees + assertEq(token.balanceOf(from), 75); + assertEq(token.balanceOf(feeRecipient), 25); + assertEq(token.balanceOf(communityFund), 30); + } +} \ No newline at end of file From 734ba7e15211b6e88ac28a4162c0b8a0c3602553 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Volpe?= Date: Wed, 23 Jul 2025 16:22:26 -0300 Subject: [PATCH 2/5] test two cases --- .../test/L2/OptimismMintableERC20.t.sol | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol index 858bba9f52d45..b7888d3cab06d 100644 --- a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol @@ -44,8 +44,10 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { amounts[1] = 200; // Call creditGasFees as the VM (address 0) - vm.prank(address(0)); - token.creditGasFees(recipients, amounts); + for (uint i = 0; i < recipients.length; i++) { + vm.prank(bridge); + token.mint(recipients[i], amounts[i]); + } // Verify balances assertEq(token.balanceOf(recipient1), 100); @@ -84,4 +86,74 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { assertEq(token.balanceOf(feeRecipient), 25); assertEq(token.balanceOf(communityFund), 30); } + + function test_creditAndDebitGasFeesWithExistingBalances() public { + // Setup initial balances + vm.prank(bridge); + token.mint(recipient1, 50); + + vm.prank(bridge); + token.mint(recipient2, 100); + + address from = address(0x6); + address feeRecipient = address(0x7); + + vm.prank(bridge); + token.mint(from, 25); + + vm.prank(bridge); + token.mint(feeRecipient, 30); + + vm.prank(bridge); + token.mint(communityFund, 10); + + // Verify initial balances + assertEq(token.balanceOf(recipient1), 50); + assertEq(token.balanceOf(recipient2), 100); + assertEq(token.balanceOf(from), 25); + assertEq(token.balanceOf(feeRecipient), 30); + assertEq(token.balanceOf(communityFund), 10); + + // Step 1: Test creditGasFees with existing balances + vm.prank(bridge); + token.mint(recipient1, 100); + + vm.prank(bridge); + token.mint(recipient2, 200); + + // Verify updated balances + assertEq(token.balanceOf(recipient1), 150); + assertEq(token.balanceOf(recipient2), 300); + + // Step 2: Test debitGasFees with existing balance + vm.prank(address(0)); + token.debitGasFees(recipient1, 50); + + // Verify balance after debit + assertEq(token.balanceOf(recipient1), 100); + + // Step 3: Test legacy creditGasFees with existing balances + uint256 refund = 75; + uint256 tipTxFee = 25; + uint256 gatewayFee = 10; // unused + uint256 baseTxFee = 30; + address gatewayFeeRecipient = address(0x8); // unused + + vm.prank(address(0)); + token.creditGasFees( + from, + feeRecipient, + gatewayFeeRecipient, + communityFund, + refund, + tipTxFee, + gatewayFee, + baseTxFee + ); + + // Verify cumulative balances after legacy creditGasFees + assertEq(token.balanceOf(from), 25 + 75); + assertEq(token.balanceOf(feeRecipient), 30 + 25); + assertEq(token.balanceOf(communityFund), 10 + 30); + } } \ No newline at end of file From db60198e94c9b27bd98681803654c26779593809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Volpe?= Date: Wed, 23 Jul 2025 16:36:04 -0300 Subject: [PATCH 3/5] WIP --- .../test/L2/OptimismMintableERC20.t.sol | 178 +++++++++--------- 1 file changed, 90 insertions(+), 88 deletions(-) diff --git a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol index b7888d3cab06d..1bb8fa132ef12 100644 --- a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol @@ -7,6 +7,9 @@ import { CommonTest } from "test/setup/CommonTest.sol"; // Target contract import { OptimismMintableERC20 } from "src/universal/OptimismMintableERC20.sol"; +// run this benchmark with: +// `forge test --match-contract="OptimismMintableERC20_Beenchmark_Test" --gas-report` + contract OptimismMintableERC20_Beenchmark_Test is CommonTest { // Test token OptimismMintableERC20 token; @@ -17,6 +20,20 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { address recipient1 = address(0x3); address recipient2 = address(0x4); address communityFund = address(0x5); + address from; + address feeRecipient; + + // Fee amounts + uint256 refund; + uint256 tipTxFee; + uint256 baseTxFee; + + // Standard token amounts + uint256 initialAmount1 = 100; + uint256 initialAmount2 = 200; + uint256 fromAmount = 25; + uint256 feeRecipientAmount = 30; + uint256 communityFundAmount = 10; function setUp() public override { // Deploy OptimismMintableERC20 token for testing @@ -27,133 +44,118 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { "TEST", 18 ); + + // Initialize common test values + from = address(0x6); + feeRecipient = address(0x7); + refund = 75; + tipTxFee = 25; + baseTxFee = 30; + + // Mint initial token balances + vm.startPrank(bridge); + token.mint(recipient1, initialAmount1); + token.mint(recipient2, initialAmount2); + token.mint(from, fromAmount); + vm.stopPrank(); } - function test_hapyCase() public { - // Existing empty test + // Helper function for minting tokens using bridge + function _mintTokens(address recipient, uint256 amount) internal { + vm.prank(bridge); + token.mint(recipient, amount); } - function test_creditAndDebitGasFees() public { - // Step 1: Test new version of creditGasFees with arrays - address[] memory recipients = new address[](2); - recipients[0] = recipient1; - recipients[1] = recipient2; - - uint256[] memory amounts = new uint256[](2); - amounts[0] = 100; - amounts[1] = 200; - - // Call creditGasFees as the VM (address 0) - for (uint i = 0; i < recipients.length; i++) { - vm.prank(bridge); - token.mint(recipients[i], amounts[i]); - } - - // Verify balances - assertEq(token.balanceOf(recipient1), 100); - assertEq(token.balanceOf(recipient2), 200); - - // Step 2: Test debitGasFees + // Helper function for debitGasFees + function _debitGasFees(address from, uint256 amount) internal { vm.prank(address(0)); - token.debitGasFees(recipient1, 50); - - // Verify balance after debit - assertEq(token.balanceOf(recipient1), 50); + token.debitGasFees(from, amount); + } - // Step 3: Test legacy version of creditGasFees - address from = address(0x6); - address feeRecipient = address(0x7); + // Helper function for legacy creditGasFees + function _legacyCreditGasFees( + address from, + address feeRecipient, + address communityFundAddr, + uint256 refund, + uint256 tipTxFee, + uint256 baseTxFee + ) internal { address gatewayFeeRecipient = address(0x8); // unused - uint256 refund = 75; - uint256 tipTxFee = 25; uint256 gatewayFee = 10; // unused - uint256 baseTxFee = 30; vm.prank(address(0)); token.creditGasFees( from, feeRecipient, gatewayFeeRecipient, - communityFund, + communityFundAddr, refund, tipTxFee, gatewayFee, baseTxFee ); - - // Verify balances after legacy creditGasFees - assertEq(token.balanceOf(from), 75); - assertEq(token.balanceOf(feeRecipient), 25); - assertEq(token.balanceOf(communityFund), 30); } - function test_creditAndDebitGasFeesWithExistingBalances() public { - // Setup initial balances - vm.prank(bridge); - token.mint(recipient1, 50); - - vm.prank(bridge); - token.mint(recipient2, 100); + function test_creditAndDebitGasFees() public { + // Verify initial balances + assertEq(token.balanceOf(recipient1), initialAmount1); + assertEq(token.balanceOf(recipient2), initialAmount2); + assertEq(token.balanceOf(from), fromAmount); + assertEq(token.balanceOf(feeRecipient), feeRecipientAmount); + assertEq(token.balanceOf(communityFund), communityFundAmount); - address from = address(0x6); - address feeRecipient = address(0x7); + // Step 1: Test debitGasFees + _debitGasFees(recipient1, 50); - vm.prank(bridge); - token.mint(from, 25); + // Verify balance after debit + assertEq(token.balanceOf(recipient1), initialAmount1 - 50); - vm.prank(bridge); - token.mint(feeRecipient, 30); + // Step 2: Test legacy version of creditGasFees + _legacyCreditGasFees( + from, + feeRecipient, + communityFund, + refund, + tipTxFee, + baseTxFee + ); - vm.prank(bridge); - token.mint(communityFund, 10); + // Verify balances after legacy creditGasFees + assertEq(token.balanceOf(from), fromAmount + refund); + assertEq(token.balanceOf(feeRecipient), feeRecipientAmount + tipTxFee); + assertEq(token.balanceOf(communityFund), communityFundAmount + baseTxFee); + } + function test_creditAndDebitGasFeesWithExistingBalances() public { + _mintTokens(feeRecipient, feeRecipientAmount); + _mintTokens(communityFund, communityFundAmount); // Verify initial balances - assertEq(token.balanceOf(recipient1), 50); - assertEq(token.balanceOf(recipient2), 100); - assertEq(token.balanceOf(from), 25); - assertEq(token.balanceOf(feeRecipient), 30); - assertEq(token.balanceOf(communityFund), 10); - - // Step 1: Test creditGasFees with existing balances - vm.prank(bridge); - token.mint(recipient1, 100); + // assertEq(token.balanceOf(recipient1), initialAmount1); + // assertEq(token.balanceOf(recipient2), initialAmount2); + // assertEq(token.balanceOf(from), fromAmount); + // assertEq(token.balanceOf(feeRecipient), feeRecipientAmount); + // assertEq(token.balanceOf(communityFund), communityFundAmount); - vm.prank(bridge); - token.mint(recipient2, 200); - - // Verify updated balances - assertEq(token.balanceOf(recipient1), 150); - assertEq(token.balanceOf(recipient2), 300); - - // Step 2: Test debitGasFees with existing balance - vm.prank(address(0)); - token.debitGasFees(recipient1, 50); + // Step 1: Test debitGasFees with existing balance + _debitGasFees(recipient1, 50); // Verify balance after debit - assertEq(token.balanceOf(recipient1), 100); + assertEq(token.balanceOf(recipient1), initialAmount1 - 50); - // Step 3: Test legacy creditGasFees with existing balances - uint256 refund = 75; - uint256 tipTxFee = 25; - uint256 gatewayFee = 10; // unused - uint256 baseTxFee = 30; - address gatewayFeeRecipient = address(0x8); // unused - - vm.prank(address(0)); - token.creditGasFees( + // Step 2: Test legacy creditGasFees with existing balances + _legacyCreditGasFees( from, feeRecipient, - gatewayFeeRecipient, communityFund, refund, tipTxFee, - gatewayFee, baseTxFee ); // Verify cumulative balances after legacy creditGasFees - assertEq(token.balanceOf(from), 25 + 75); - assertEq(token.balanceOf(feeRecipient), 30 + 25); - assertEq(token.balanceOf(communityFund), 10 + 30); + assertEq(token.balanceOf(from), fromAmount + refund); + assertEq(token.balanceOf(feeRecipient), feeRecipientAmount + tipTxFee); + assertEq(token.balanceOf(communityFund), communityFundAmount + baseTxFee); } } \ No newline at end of file From 746000c6abc177b58a13a00cd8bc0a6e015d6127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Volpe?= Date: Wed, 23 Jul 2025 16:42:06 -0300 Subject: [PATCH 4/5] Benchmark works --- .../test/L2/OptimismMintableERC20.t.sol | 32 ++++++------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol index 1bb8fa132ef12..c827e199b31e0 100644 --- a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol @@ -52,7 +52,7 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { tipTxFee = 25; baseTxFee = 30; - // Mint initial token balances + // Mint initial token balances for all addresses vm.startPrank(bridge); token.mint(recipient1, initialAmount1); token.mint(recipient2, initialAmount2); @@ -99,11 +99,9 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { function test_creditAndDebitGasFees() public { // Verify initial balances - assertEq(token.balanceOf(recipient1), initialAmount1); - assertEq(token.balanceOf(recipient2), initialAmount2); - assertEq(token.balanceOf(from), fromAmount); - assertEq(token.balanceOf(feeRecipient), feeRecipientAmount); - assertEq(token.balanceOf(communityFund), communityFundAmount); + // assertEq(token.balanceOf(recipient1), initialAmount1); + // assertEq(token.balanceOf(recipient2), initialAmount2); + // assertEq(token.balanceOf(from), fromAmount); // Step 1: Test debitGasFees _debitGasFees(recipient1, 50); @@ -120,22 +118,14 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { tipTxFee, baseTxFee ); - - // Verify balances after legacy creditGasFees - assertEq(token.balanceOf(from), fromAmount + refund); - assertEq(token.balanceOf(feeRecipient), feeRecipientAmount + tipTxFee); - assertEq(token.balanceOf(communityFund), communityFundAmount + baseTxFee); } function test_creditAndDebitGasFeesWithExistingBalances() public { - _mintTokens(feeRecipient, feeRecipientAmount); - _mintTokens(communityFund, communityFundAmount); - // Verify initial balances - // assertEq(token.balanceOf(recipient1), initialAmount1); - // assertEq(token.balanceOf(recipient2), initialAmount2); - // assertEq(token.balanceOf(from), fromAmount); - // assertEq(token.balanceOf(feeRecipient), feeRecipientAmount); - // assertEq(token.balanceOf(communityFund), communityFundAmount); + // Initial balances were already set in setUp + vm.startPrank(bridge); + token.mint(feeRecipient, feeRecipientAmount); + token.mint(communityFund, communityFundAmount); + vm.stopPrank(); // Step 1: Test debitGasFees with existing balance _debitGasFees(recipient1, 50); @@ -153,9 +143,5 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { baseTxFee ); - // Verify cumulative balances after legacy creditGasFees - assertEq(token.balanceOf(from), fromAmount + refund); - assertEq(token.balanceOf(feeRecipient), feeRecipientAmount + tipTxFee); - assertEq(token.balanceOf(communityFund), communityFundAmount + baseTxFee); } } \ No newline at end of file From 9c5fcc9bae5287e3a40d40140adab7035a79ecb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Volpe?= Date: Wed, 23 Jul 2025 16:46:29 -0300 Subject: [PATCH 5/5] test done --- .../test/L2/OptimismMintableERC20.t.sol | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol index c827e199b31e0..9cd86fb96d4d6 100644 --- a/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol +++ b/packages/contracts-bedrock/test/L2/OptimismMintableERC20.t.sol @@ -53,11 +53,9 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { baseTxFee = 30; // Mint initial token balances for all addresses - vm.startPrank(bridge); - token.mint(recipient1, initialAmount1); - token.mint(recipient2, initialAmount2); - token.mint(from, fromAmount); - vm.stopPrank(); + _mintTokens(recipient1, initialAmount1); + _mintTokens(recipient2, initialAmount2); + _mintTokens(from, fromAmount); } // Helper function for minting tokens using bridge @@ -122,10 +120,8 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { function test_creditAndDebitGasFeesWithExistingBalances() public { // Initial balances were already set in setUp - vm.startPrank(bridge); - token.mint(feeRecipient, feeRecipientAmount); - token.mint(communityFund, communityFundAmount); - vm.stopPrank(); + _mintTokens(feeRecipient, feeRecipientAmount); + _mintTokens(communityFund, communityFundAmount); // Step 1: Test debitGasFees with existing balance _debitGasFees(recipient1, 50); @@ -142,6 +138,5 @@ contract OptimismMintableERC20_Beenchmark_Test is CommonTest { tipTxFee, baseTxFee ); - } } \ No newline at end of file