From e7da9fd6a73f86df00ce6a479472d695dc0091f2 Mon Sep 17 00:00:00 2001 From: Dustin Brickwood Date: Thu, 11 Apr 2024 09:47:22 -0500 Subject: [PATCH] chore: update with staging --- content/10.quick-start/5.paymaster.md | 218 ++++++------------ .../_foundry_deploy_contract_factory.md | 2 +- .../_hardhat_deploy_contract_factory.md | 2 +- .../_index/_foundry_deploy_contract.md | 2 +- .../_index/_hardhat_deploy_contract.md | 2 +- .../_paymasters/_approval_paymaster_flow.md | 0 .../_general_paymaster_flow copy.md | 0 .../_testing/_hardhat_contract_testing.md | 2 +- .../_foundry_beacon_contract_upgradability.md | 215 +---------------- ...ndry_transparent_contract_upgradability.md | 215 +---------------- .../_foundry_uups_contract_upgradability.md | 215 +---------------- 11 files changed, 85 insertions(+), 788 deletions(-) create mode 100644 content/10.quick-start/_paymasters/_approval_paymaster_flow.md create mode 100644 content/10.quick-start/_paymasters/_general_paymaster_flow copy.md diff --git a/content/10.quick-start/5.paymaster.md b/content/10.quick-start/5.paymaster.md index 8f8fbae5..63f28dfb 100644 --- a/content/10.quick-start/5.paymaster.md +++ b/content/10.quick-start/5.paymaster.md @@ -3,153 +3,83 @@ title: Paymaster description: Learn how to write and customize your documentation. --- -This is only a basic example of what you can achieve with [Nuxt UI Pro](https://ui.nuxt.com/pro/guide), you can tweak it -to match your needs. The template uses several Nuxt modules underneath like [`@nuxt/content`](https://content.nuxt.com) -for the content, [`@nuxtjs/fontaine`](https://github.com/nuxt-modules/fontaine) and -[`@nuxtjs/google-fonts`](https://github.com/nuxt-modules/google-fonts) to change the font and -[`nuxt-og-image`](https://nuxtseo.com/og-image/getting-started/installation) for social previews. +WWelcome back to our Quickstart Series on mastering zkSync development! In this guide, we move beyond the basics +of smart contract deployment and the creation of contract factories to explore the innovative concept of paymasters +in the zkSync ecosystem. This guide will illuminate the power of paymasters to revolutionize transaction +fee management and enhance user experiences within your dApps. -## ::callout +:check-icon Delving deeper into zkSync development with the introduction of paymasters. -icon: i-heroicons-light-bulb target: \_blank to: [nuxt guide](https://ui.nuxt.com/pro/guide/usage#structure) +:check-icon Learning how paymasters can cover transaction fees for your dApp users, enhancing accessibility and user experience. ---- +:check-icon Discovering the flexibility of fee payment with paymasters, including the ability to pay +fees in ERC20 tokens on zkSync Era, using Hardhat or Foundry. -Learn more on how to customize and structure a Nuxt UI Pro app! :: - -## Writing content - -You can just start writing `.md` or `.yml` files in the [`content/`](https://content.nuxt.com/usage/content-directory) -directory to have your pages updated. The navigation will be automatically generated in the left aside and in the mobile -menu. You will also be able to go through your content with full-text search. - -::callout{icon="i-heroicons-light-bulb"} This template relies on a -[catch-all route](https://nuxt.com/docs/guide/directory-structure/pages#catch-all-route) but you can achieve the same -thing with the [document-driven mode](https://content.nuxt.com/document-driven/introduction). :: - -## App Configuration - -In addition to `@nuxt/ui-pro` configuration through the `app.config.ts`, this template lets you customize the `Header`, -`Footer` and the `Table of contents` components. - -### Header - -```ts [app.config.ts] -export default defineAppConfig({ - header: { - // Logo configuration - logo: { - // Light mode - light: { - src: '', - alt: '', - class: '', - }, - // Dark mode - dark: { - src: '', - alt: '', - class: '', - }, - }, - // Show or hide the search bar - search: true, - // Show or hide the color mode button - colorMode: true, - // Customize links - links: [ - { - icon: 'i-simple-icons-github', - to: 'https://github.com/nuxt-ui-pro/docs', - target: '_blank', - 'aria-label': 'Docs template on GitHub', - }, - ], - }, -}); -``` - -### Footer - -```ts [app.config.ts] -export default defineAppConfig({ - footer: { - // Update bottom left credits - credits: 'Copyright © 2023', - // Show or hide the color mode button - colorMode: false, - // Customize links - links: [ - { - icon: 'i-simple-icons-nuxtdotjs', - to: 'https://nuxt.com', - target: '_blank', - 'aria-label': 'Nuxt Website', - }, - { - icon: 'i-simple-icons-discord', - to: 'https://discord.com/invite/ps2h6QT', - target: '_blank', - 'aria-label': 'Nuxt UI on Discord', - }, - { - icon: 'i-simple-icons-x', - to: 'https://x.com/nuxt_js', - target: '_blank', - 'aria-label': 'Nuxt on X', - }, - { - icon: 'i-simple-icons-github', - to: 'https://github.com/nuxt/ui', - target: '_blank', - 'aria-label': 'Nuxt UI on GitHub', - }, - ], - }, -}); -``` - -### Table of contents - -```ts [app.config.ts] -export default defineAppConfig({ - toc: { - // Title of the main table of contents - title: 'Table of Contents', - // Bottom TOC configuration - bottom: { - // Title of the bottom table of contents - title: 'Community', - // URL of your repository content folder - edit: '', - // Customize links - links: [ - { - icon: 'i-heroicons-star', - label: 'Star on GitHub', - to: 'https://github.com/nuxt/ui', - target: '_blank', - }, - { - icon: 'i-heroicons-book-open', - label: 'Nuxt UI Pro docs', - to: 'https://ui.nuxt.com/pro/guide', - target: '_blank', - }, - { - icon: 'i-simple-icons-nuxtdotjs', - label: 'Purchase a license', - to: 'https://ui.nuxt.com/pro/purchase', - target: '_blank', - }, - ], - }, - }, -}); -``` - -icon: i-heroicons-light-bulb target: \_blank to: [app-config](https://nuxt.studio/docs/developers/app-config) +Embark on this journey to understand how paymasters can add a new layer of functionality and user-friendliness +to your decentralized applications. ---- +### What are Paymasters? + +Paymasters in the zkSync ecosystem represent a groundbreaking approach to handling transaction fees. +They are special accounts designed to subsidize transaction costs for other accounts, potentially making +certain transactions free for end-users. This feature is particularly useful for dApp developers looking +to improve their platform's accessibility and user experience by covering transaction fees on behalf of their users. + +### Built-in Paymaster Flows + +Paymasters can operate under various flows, some of which may require user interaction, such as setting allowances +for token swaps. These flows enable paymasters to support a wide range of use cases, from simple fee subsidies +to more complex scenarios involving ERC20 token exchanges for transaction fees. + +- **General Paymaster Flow:** This default flow requires no preliminary actions from users, allowing paymasters +to interpret transaction data as needed to cover fees. + +- **Approval-Based Paymaster Flow:** For operations requiring user permissions, such as token allowances, +this flow provides a structured approach. It ensures that user tokens can be seamlessly exchanged for transaction +fees, subject to user-approved limits. -A dedicated interface is provided to edit those configurations on Nuxt Studio. :: +As we delve into paymasters, remember that while they offer enhanced flexibility for fee management, their +implementation should always prioritize security and user trust. This guide aims to equip you with the knowledge +to effectively incorporate paymasters into your zkSync projects, paving the way for more user-friendly and accessible dApps. + +## Framework selection + +Select the framework you want to get started using zkSync Era with. + +::content-switcher +--- +items: [{ + label: 'Hardhat', + partial: '_deploy_factory/_hardhat_deploy_contract_factory' +}, { + label: 'Foundry', + partial: '_deploy_factory/_foundry_deploy_contract_factory' +}] +--- +:: + +## Takeaways + +- **Contract Factories:** Utilizing contract factories significantly streamlines +the deployment process, allowing for the creation of multiple instances of a +contract, like the `CrowdfundingCampaign`, with varied parameters. +- **Scalability and Management:** Contract factories offer a scalable solution to manage +numerous contract instances, enhancing project organization and efficiency. +- **Event-Driven Insights:** The `CampaignCreated` event in the factory contract provides +a transparent mechanism to track each crowdfunding campaign's deployment, useful for +off-chain monitoring and interaction. + +## Next steps + +With the contract factory in your zkSync development arsenal, you're set to elevate +your smart contract projects. Here's how you can further your journey: + +- **Contract Testing:** Progress to the next guide focused on testing your contracts. +Ensuring the reliability and security of your `CrowdfundingCampaign` through +comprehensive tests is critical. +- **Advanced zkSync Integrations:** Explore deeper into zkSync's ecosystem by +implementing features like account abstraction and paymasters to enhance user +experience and contract flexibility. +- **Community Engagement and Contribution:** Join the vibrant zkSync community. +Participate in forums, Discord, or GitHub discussions. Sharing insights, asking queries, +and contributing can enrich the ecosystem and your understanding of zkSync. diff --git a/content/10.quick-start/_deploy_factory/_foundry_deploy_contract_factory.md b/content/10.quick-start/_deploy_factory/_foundry_deploy_contract_factory.md index d21b852d..da67357e 100644 --- a/content/10.quick-start/_deploy_factory/_foundry_deploy_contract_factory.md +++ b/content/10.quick-start/_deploy_factory/_foundry_deploy_contract_factory.md @@ -147,7 +147,7 @@ contractAddress 0x95f83473b88B5599cdB273F976fB3DC66DEA1c1D ... ``` -Key Components: +**Key Components:** **Deployment Workflow:** diff --git a/content/10.quick-start/_deploy_factory/_hardhat_deploy_contract_factory.md b/content/10.quick-start/_deploy_factory/_hardhat_deploy_contract_factory.md index 52a6acb2..3777afcd 100644 --- a/content/10.quick-start/_deploy_factory/_hardhat_deploy_contract_factory.md +++ b/content/10.quick-start/_deploy_factory/_hardhat_deploy_contract_factory.md @@ -148,7 +148,7 @@ export default async function (hre: HardhatRuntimeEnvironment) { } ``` -Key Components: +**Key Components:** **Deployment Workflow:** diff --git a/content/10.quick-start/_index/_foundry_deploy_contract.md b/content/10.quick-start/_index/_foundry_deploy_contract.md index 2df26237..082d4053 100644 --- a/content/10.quick-start/_index/_foundry_deploy_contract.md +++ b/content/10.quick-start/_index/_foundry_deploy_contract.md @@ -143,7 +143,7 @@ contract DeployCrowdfundContract is Script { } ``` -Key Components: +**Key Components:** - **contractArtifactName:** Identifies the `CrowdfundingCampaign` contract for deployment. - **constructorArguments:** Sets initialization parameters for the contract. diff --git a/content/10.quick-start/_index/_hardhat_deploy_contract.md b/content/10.quick-start/_index/_hardhat_deploy_contract.md index 6ab8c0e6..839eabcf 100644 --- a/content/10.quick-start/_index/_hardhat_deploy_contract.md +++ b/content/10.quick-start/_index/_hardhat_deploy_contract.md @@ -141,7 +141,7 @@ export default async function () { } ``` -Key Components: +**Key Components:** - **contractArtifactName:** Identifies the `CrowdfundingCampaign` contract for deployment. - **constructorArguments:** Sets initialization parameters for the contract. In this case, diff --git a/content/10.quick-start/_paymasters/_approval_paymaster_flow.md b/content/10.quick-start/_paymasters/_approval_paymaster_flow.md new file mode 100644 index 00000000..e69de29b diff --git a/content/10.quick-start/_paymasters/_general_paymaster_flow copy.md b/content/10.quick-start/_paymasters/_general_paymaster_flow copy.md new file mode 100644 index 00000000..e69de29b diff --git a/content/10.quick-start/_testing/_hardhat_contract_testing.md b/content/10.quick-start/_testing/_hardhat_contract_testing.md index 767fb2c8..ff442e3e 100644 --- a/content/10.quick-start/_testing/_hardhat_contract_testing.md +++ b/content/10.quick-start/_testing/_hardhat_contract_testing.md @@ -202,7 +202,7 @@ describe("CrowdfundingCampaign", function () { }); ``` -Key Components: +**Key Components:** **Testing Workflow:** diff --git a/content/10.quick-start/_upgrading/_beacon/_foundry_beacon_contract_upgradability.md b/content/10.quick-start/_upgrading/_beacon/_foundry_beacon_contract_upgradability.md index 03cdb7d9..6876ce71 100644 --- a/content/10.quick-start/_upgrading/_beacon/_foundry_beacon_contract_upgradability.md +++ b/content/10.quick-start/_upgrading/_beacon/_foundry_beacon_contract_upgradability.md @@ -1,216 +1,5 @@ --- -title: Hardhat | Beacon +title: Foundry | Contract Upgrade --- -`foundry-zksync` is a specialized fork of Foundry, tailored for zkSync. -It extends Foundry's capabilities for Ethereum app development to support zkSync, -allowing for the compilation, deployment, testing, and interaction with smart contracts on zkSync. - -::callout{icon="i-heroicons-information-circle-16-solid" color="amber"} -`foundry-zksync` is still in an alpha stage, so some features might not be fully supported -yet and may not work as fully intended. It is open-sourced and contributions are welcomed. -:: - -## Step 1: Environment Configuration - -## Step 2: Test Wallet Configuration - -## Step 3: Testing `CrowdfundingCampaign` contract - -Now that our setup is complete, it's time to focus on the core of this -guide - testing our `CrowdfundingCampaign.sol` contract. Here's a quick -refresher on its structure: - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract CrowdfundingCampaign { - address public owner; - uint256 public fundingGoal; - uint256 public totalFundsRaised; - mapping(address => uint256) public contributions; - - event ContributionReceived(address contributor, uint256 amount); - event GoalReached(uint256 totalFundsRaised); - - constructor(uint256 _fundingGoal) { - owner = msg.sender; - fundingGoal = _fundingGoal; - } - - function contribute() public payable { - require(msg.value > 0, "Contribution must be greater than 0"); - contributions[msg.sender] += msg.value; - totalFundsRaised += msg.value; - - emit ContributionReceived(msg.sender, msg.value); - - if (totalFundsRaised >= fundingGoal) { - emit GoalReached(totalFundsRaised); - } - } - - function withdrawFunds() public { - require(msg.sender == owner, "Only the owner can withdraw funds"); - require(totalFundsRaised >= fundingGoal, "Funding goal not reached"); - - uint256 amount = address(this).balance; - totalFundsRaised = 0; - - (bool success, ) = payable(owner).call{value: amount}(""); - require(success, "Transfer failed."); - } - - function getTotalFundsRaised() public view returns (uint256) { - return totalFundsRaised; - } - - function getFundingGoal() public view returns (uint256) { - return fundingGoal; - } -} -``` - -Thorough testing involves scrutinizing every function and aspect of our contract, -including potential failure scenarios. In this guide, we'll focus in on the `contribute` -method to ensure it's tested. - -As a challenge to hone your testing skills further, -consider devising additional tests for the `withdrawFunds`, `getTotalFundsRaised`, -and `getFundingGoal` methods, expanding your test coverage and reinforcing the -reliability of the contract. - -### Compile contract - -Smart contracts deployed to zkSync must be compiled using our custom compiler. -For this particular guide we are making use of `zksolc`. - -To compile the contracts in the project, run the following command: - -```bash -forge build --zksync -``` - -#### Expected Output - -Upon successful compilation, you'll receive output detailing the -`zksolc` and `solc` versions used during compiling and the number -of Solidity files compiled. - -```bash -[⠒] Compiling... -[⠃] Compiling 22 files with 0.8.20 -[⠊] Solc 0.8.20 finished in 736.48ms -Compiler run successful! -Compiling contracts for zkSync Era with zksolc v1.4.0 -``` - -The compiled zkEVM artifacts will be located in the `/zkout` folder, and the solc artifacts will be -located in the `/out` folder. - -### Testing - -This section describes the testing `CrowdfundingCampaign.sol` contract. Let's -start by reviewing the tests for `CrowdfundingCampaign.sol` contract provided -during the initialization step in the `/test` directory, specifically the -`CrowdfundingCampaign.t.sol` file. - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; -import "../src/CrowdfundingCampaign.sol"; - -contract CrowdfundingCampaignTest is Test { - CrowdfundingCampaign campaign; - event GoalReached(uint256 totalFundsRaised); - address owner; - address addr1; - address addr2; - - function setUp() public { - owner = address(this); - - addr1 = vm.addr(1); - addr2 = vm.addr(2); - - campaign = new CrowdfundingCampaign(1 ether); - console.log("CrowdfundingCampaign deployed at: %s", address(campaign)); - } - - function test_RejectZeroContributions() public { - vm.expectRevert("Contribution must be greater than 0"); - campaign.contribute{value: 0}(); - } - - function test_AggregateContributions() public { - uint256 initialTotal = campaign.getTotalFundsRaised(); - - vm.prank(addr1); - vm.deal(addr1, 2 ether); - campaign.contribute{value: 0.5 ether}(); - - vm.prank(addr2); - vm.deal(addr2, 2 ether); - campaign.contribute{value: 0.3 ether}(); - - assertEq(campaign.getTotalFundsRaised(), initialTotal + 0.8 ether); - } - - function test_EmitGoalReachedWhenFundingGoalMet() public { - vm.prank(addr1); - vm.deal(addr1, 2 ether); - vm.expectEmit(true, true, false, true); - emit GoalReached(1 ether); - campaign.contribute{value: 1 ether}(); - } -} - -``` - -**Testing Workflow:** - -- **Environment Setup**: Leverages Foundry's `Test` contract and setup functions -to prepare the test environment, ensuring a fresh state for each test case. -- **Deployment and Address Simulation**: Deploys the `CrowdfundingCampaign` contract -within the test setup and simulates addresses using Foundry's `vm.addr()` function for -various test actors. - -**`contribute` Method Tests:** - -- **Zero Contribution Validation**: Asserts that the contract rejects contribution -attempts with zero value, testing the contract's input validation logic. -- **Contribution Aggregation**: Confirms the contract's ability to correctly tally -contributions from various addresses, ensuring accurate tracking of the total funds raised. -- **Event Emission Upon Goal Achievement**: Utilizes Foundry's `vm.expectEmit` to -anticipate the `GoalReached` event when the funding goal is met, validating the -contract's event logic and state transitions. - -#### Execute tests - -Execute the test command: - -```bash -forge test --zksync -``` - -#### Expected Output - -Upon completion, the test suite will provide a summary of all executed tests, -indicating their success or failure: - -```bash -Ran 3 tests for test/CrowdfundingCampaign.t.sol:CrowdfundingCampaignTest -[PASS] test_AggregateContributions() (gas: 29204) -[PASS] test_EmitGoalReachedWhenFundingGoalMet() (gas: 18862) -[PASS] test_RejectZeroContributions() (gas: 8148) -Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 44.03ms (43.94ms CPU time) - -Ran 1 test suite in 48.11ms (44.03ms CPU time): 3 tests passed, 0 failed, 0 skipped (3 total tests) -``` - -🎉 Congratulations! The `contribute` method of the `CrowdfundingCampaign` contract -has been thoroughly tested and is ready for action. +Coming soon! diff --git a/content/10.quick-start/_upgrading/_transparent/_foundry_transparent_contract_upgradability.md b/content/10.quick-start/_upgrading/_transparent/_foundry_transparent_contract_upgradability.md index ae788953..6876ce71 100644 --- a/content/10.quick-start/_upgrading/_transparent/_foundry_transparent_contract_upgradability.md +++ b/content/10.quick-start/_upgrading/_transparent/_foundry_transparent_contract_upgradability.md @@ -1,216 +1,5 @@ --- -title: Hardhat | Contract Testing +title: Foundry | Contract Upgrade --- -`foundry-zksync` is a specialized fork of Foundry, tailored for zkSync. -It extends Foundry's capabilities for Ethereum app development to support zkSync, -allowing for the compilation, deployment, testing, and interaction with smart contracts on zkSync. - -::callout{icon="i-heroicons-information-circle-16-solid" color="amber"} -`foundry-zksync` is still in an alpha stage, so some features might not be fully supported -yet and may not work as fully intended. It is open-sourced and contributions are welcomed. -:: - -## Step 1: Environment Configuration - -## Step 2: Test Wallet Configuration - -## Step 3: Testing `CrowdfundingCampaign` contract - -Now that our setup is complete, it's time to focus on the core of this -guide - testing our `CrowdfundingCampaign.sol` contract. Here's a quick -refresher on its structure: - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract CrowdfundingCampaign { - address public owner; - uint256 public fundingGoal; - uint256 public totalFundsRaised; - mapping(address => uint256) public contributions; - - event ContributionReceived(address contributor, uint256 amount); - event GoalReached(uint256 totalFundsRaised); - - constructor(uint256 _fundingGoal) { - owner = msg.sender; - fundingGoal = _fundingGoal; - } - - function contribute() public payable { - require(msg.value > 0, "Contribution must be greater than 0"); - contributions[msg.sender] += msg.value; - totalFundsRaised += msg.value; - - emit ContributionReceived(msg.sender, msg.value); - - if (totalFundsRaised >= fundingGoal) { - emit GoalReached(totalFundsRaised); - } - } - - function withdrawFunds() public { - require(msg.sender == owner, "Only the owner can withdraw funds"); - require(totalFundsRaised >= fundingGoal, "Funding goal not reached"); - - uint256 amount = address(this).balance; - totalFundsRaised = 0; - - (bool success, ) = payable(owner).call{value: amount}(""); - require(success, "Transfer failed."); - } - - function getTotalFundsRaised() public view returns (uint256) { - return totalFundsRaised; - } - - function getFundingGoal() public view returns (uint256) { - return fundingGoal; - } -} -``` - -Thorough testing involves scrutinizing every function and aspect of our contract, -including potential failure scenarios. In this guide, we'll focus in on the `contribute` -method to ensure it's tested. - -As a challenge to hone your testing skills further, -consider devising additional tests for the `withdrawFunds`, `getTotalFundsRaised`, -and `getFundingGoal` methods, expanding your test coverage and reinforcing the -reliability of the contract. - -### Compile contract - -Smart contracts deployed to zkSync must be compiled using our custom compiler. -For this particular guide we are making use of `zksolc`. - -To compile the contracts in the project, run the following command: - -```bash -forge build --zksync -``` - -#### Expected Output - -Upon successful compilation, you'll receive output detailing the -`zksolc` and `solc` versions used during compiling and the number -of Solidity files compiled. - -```bash -[⠒] Compiling... -[⠃] Compiling 22 files with 0.8.20 -[⠊] Solc 0.8.20 finished in 736.48ms -Compiler run successful! -Compiling contracts for zkSync Era with zksolc v1.4.0 -``` - -The compiled zkEVM artifacts will be located in the `/zkout` folder, and the solc artifacts will be -located in the `/out` folder. - -### Testing - -This section describes the testing `CrowdfundingCampaign.sol` contract. Let's -start by reviewing the tests for `CrowdfundingCampaign.sol` contract provided -during the initialization step in the `/test` directory, specifically the -`CrowdfundingCampaign.t.sol` file. - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; -import "../src/CrowdfundingCampaign.sol"; - -contract CrowdfundingCampaignTest is Test { - CrowdfundingCampaign campaign; - event GoalReached(uint256 totalFundsRaised); - address owner; - address addr1; - address addr2; - - function setUp() public { - owner = address(this); - - addr1 = vm.addr(1); - addr2 = vm.addr(2); - - campaign = new CrowdfundingCampaign(1 ether); - console.log("CrowdfundingCampaign deployed at: %s", address(campaign)); - } - - function test_RejectZeroContributions() public { - vm.expectRevert("Contribution must be greater than 0"); - campaign.contribute{value: 0}(); - } - - function test_AggregateContributions() public { - uint256 initialTotal = campaign.getTotalFundsRaised(); - - vm.prank(addr1); - vm.deal(addr1, 2 ether); - campaign.contribute{value: 0.5 ether}(); - - vm.prank(addr2); - vm.deal(addr2, 2 ether); - campaign.contribute{value: 0.3 ether}(); - - assertEq(campaign.getTotalFundsRaised(), initialTotal + 0.8 ether); - } - - function test_EmitGoalReachedWhenFundingGoalMet() public { - vm.prank(addr1); - vm.deal(addr1, 2 ether); - vm.expectEmit(true, true, false, true); - emit GoalReached(1 ether); - campaign.contribute{value: 1 ether}(); - } -} - -``` - -**Testing Workflow:** - -- **Environment Setup**: Leverages Foundry's `Test` contract and setup functions -to prepare the test environment, ensuring a fresh state for each test case. -- **Deployment and Address Simulation**: Deploys the `CrowdfundingCampaign` contract -within the test setup and simulates addresses using Foundry's `vm.addr()` function for -various test actors. - -**`contribute` Method Tests:** - -- **Zero Contribution Validation**: Asserts that the contract rejects contribution -attempts with zero value, testing the contract's input validation logic. -- **Contribution Aggregation**: Confirms the contract's ability to correctly tally -contributions from various addresses, ensuring accurate tracking of the total funds raised. -- **Event Emission Upon Goal Achievement**: Utilizes Foundry's `vm.expectEmit` to -anticipate the `GoalReached` event when the funding goal is met, validating the -contract's event logic and state transitions. - -#### Execute tests - -Execute the test command: - -```bash -forge test --zksync -``` - -#### Expected Output - -Upon completion, the test suite will provide a summary of all executed tests, -indicating their success or failure: - -```bash -Ran 3 tests for test/CrowdfundingCampaign.t.sol:CrowdfundingCampaignTest -[PASS] test_AggregateContributions() (gas: 29204) -[PASS] test_EmitGoalReachedWhenFundingGoalMet() (gas: 18862) -[PASS] test_RejectZeroContributions() (gas: 8148) -Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 44.03ms (43.94ms CPU time) - -Ran 1 test suite in 48.11ms (44.03ms CPU time): 3 tests passed, 0 failed, 0 skipped (3 total tests) -``` - -🎉 Congratulations! The `contribute` method of the `CrowdfundingCampaign` contract -has been thoroughly tested and is ready for action. +Coming soon! diff --git a/content/10.quick-start/_upgrading/_uups/_foundry_uups_contract_upgradability.md b/content/10.quick-start/_upgrading/_uups/_foundry_uups_contract_upgradability.md index bb780bef..6876ce71 100644 --- a/content/10.quick-start/_upgrading/_uups/_foundry_uups_contract_upgradability.md +++ b/content/10.quick-start/_upgrading/_uups/_foundry_uups_contract_upgradability.md @@ -1,216 +1,5 @@ --- -title: Hardhat | Contract Testing +title: Foundry | Contract Upgrade --- -`foundry-zksync` is a sssspecialized fork of Foundry, tailored for zkSync. -It extends Foundry's capabilities for Ethereum app development to support zkSync, -allowing for the compilation, deployment, testing, and interaction with smart contracts on zkSync. - -::callout{icon="i-heroicons-information-circle-16-solid" color="amber"} -`foundry-zksync` is still in an alpha stage, so some features might not be fully supported -yet and may not work as fully intended. It is open-sourced and contributions are welcomed. -:: - -## Step 1: Environment Configuration - -## Step 2: Test Wallet Configuration - -## Step 3: Testing `CrowdfundingCampaign` contract - -Now that our setup is complete, it's time to focus on the core of this -guide - testing our `CrowdfundingCampaign.sol` contract. Here's a quick -refresher on its structure: - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract CrowdfundingCampaign { - address public owner; - uint256 public fundingGoal; - uint256 public totalFundsRaised; - mapping(address => uint256) public contributions; - - event ContributionReceived(address contributor, uint256 amount); - event GoalReached(uint256 totalFundsRaised); - - constructor(uint256 _fundingGoal) { - owner = msg.sender; - fundingGoal = _fundingGoal; - } - - function contribute() public payable { - require(msg.value > 0, "Contribution must be greater than 0"); - contributions[msg.sender] += msg.value; - totalFundsRaised += msg.value; - - emit ContributionReceived(msg.sender, msg.value); - - if (totalFundsRaised >= fundingGoal) { - emit GoalReached(totalFundsRaised); - } - } - - function withdrawFunds() public { - require(msg.sender == owner, "Only the owner can withdraw funds"); - require(totalFundsRaised >= fundingGoal, "Funding goal not reached"); - - uint256 amount = address(this).balance; - totalFundsRaised = 0; - - (bool success, ) = payable(owner).call{value: amount}(""); - require(success, "Transfer failed."); - } - - function getTotalFundsRaised() public view returns (uint256) { - return totalFundsRaised; - } - - function getFundingGoal() public view returns (uint256) { - return fundingGoal; - } -} -``` - -Thorough testing involves scrutinizing every function and aspect of our contract, -including potential failure scenarios. In this guide, we'll focus in on the `contribute` -method to ensure it's tested. - -As a challenge to hone your testing skills further, -consider devising additional tests for the `withdrawFunds`, `getTotalFundsRaised`, -and `getFundingGoal` methods, expanding your test coverage and reinforcing the -reliability of the contract. - -### Compile contract - -Smart contracts deployed to zkSync must be compiled using our custom compiler. -For this particular guide we are making use of `zksolc`. - -To compile the contracts in the project, run the following command: - -```bash -forge build --zksync -``` - -#### Expected Output - -Upon successful compilation, you'll receive output detailing the -`zksolc` and `solc` versions used during compiling and the number -of Solidity files compiled. - -```bash -[⠒] Compiling... -[⠃] Compiling 22 files with 0.8.20 -[⠊] Solc 0.8.20 finished in 736.48ms -Compiler run successful! -Compiling contracts for zkSync Era with zksolc v1.4.0 -``` - -The compiled zkEVM artifacts will be located in the `/zkout` folder, and the solc artifacts will be -located in the `/out` folder. - -### Testing - -This section describes the testing `CrowdfundingCampaign.sol` contract. Let's -start by reviewing the tests for `CrowdfundingCampaign.sol` contract provided -during the initialization step in the `/test` directory, specifically the -`CrowdfundingCampaign.t.sol` file. - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -import "forge-std/Test.sol"; -import "forge-std/console.sol"; -import "../src/CrowdfundingCampaign.sol"; - -contract CrowdfundingCampaignTest is Test { - CrowdfundingCampaign campaign; - event GoalReached(uint256 totalFundsRaised); - address owner; - address addr1; - address addr2; - - function setUp() public { - owner = address(this); - - addr1 = vm.addr(1); - addr2 = vm.addr(2); - - campaign = new CrowdfundingCampaign(1 ether); - console.log("CrowdfundingCampaign deployed at: %s", address(campaign)); - } - - function test_RejectZeroContributions() public { - vm.expectRevert("Contribution must be greater than 0"); - campaign.contribute{value: 0}(); - } - - function test_AggregateContributions() public { - uint256 initialTotal = campaign.getTotalFundsRaised(); - - vm.prank(addr1); - vm.deal(addr1, 2 ether); - campaign.contribute{value: 0.5 ether}(); - - vm.prank(addr2); - vm.deal(addr2, 2 ether); - campaign.contribute{value: 0.3 ether}(); - - assertEq(campaign.getTotalFundsRaised(), initialTotal + 0.8 ether); - } - - function test_EmitGoalReachedWhenFundingGoalMet() public { - vm.prank(addr1); - vm.deal(addr1, 2 ether); - vm.expectEmit(true, true, false, true); - emit GoalReached(1 ether); - campaign.contribute{value: 1 ether}(); - } -} - -``` - -**Testing Workflow:** - -- **Environment Setup**: Leverages Foundry's `Test` contract and setup functions -to prepare the test environment, ensuring a fresh state for each test case. -- **Deployment and Address Simulation**: Deploys the `CrowdfundingCampaign` contract -within the test setup and simulates addresses using Foundry's `vm.addr()` function for -various test actors. - -**`contribute` Method Tests:** - -- **Zero Contribution Validation**: Asserts that the contract rejects contribution -attempts with zero value, testing the contract's input validation logic. -- **Contribution Aggregation**: Confirms the contract's ability to correctly tally -contributions from various addresses, ensuring accurate tracking of the total funds raised. -- **Event Emission Upon Goal Achievement**: Utilizes Foundry's `vm.expectEmit` to -anticipate the `GoalReached` event when the funding goal is met, validating the -contract's event logic and state transitions. - -#### Execute tests - -Execute the test command: - -```bash -forge test --zksync -``` - -#### Expected Output - -Upon completion, the test suite will provide a summary of all executed tests, -indicating their success or failure: - -```bash -Ran 3 tests for test/CrowdfundingCampaign.t.sol:CrowdfundingCampaignTest -[PASS] test_AggregateContributions() (gas: 29204) -[PASS] test_EmitGoalReachedWhenFundingGoalMet() (gas: 18862) -[PASS] test_RejectZeroContributions() (gas: 8148) -Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 44.03ms (43.94ms CPU time) - -Ran 1 test suite in 48.11ms (44.03ms CPU time): 3 tests passed, 0 failed, 0 skipped (3 total tests) -``` - -🎉 Congratulations! The `contribute` method of the `CrowdfundingCampaign` contract -has been thoroughly tested and is ready for action. +Coming soon!