diff --git a/.gitbook/assets/SFS (1).png b/.gitbook/assets/SFS (1).png deleted file mode 100644 index 8279baf..0000000 Binary files a/.gitbook/assets/SFS (1).png and /dev/null differ diff --git a/.gitbook/assets/SFS Withdrawal Guide Image.png b/.gitbook/assets/SFS Withdrawal Guide Image.png deleted file mode 100644 index 28e1262..0000000 Binary files a/.gitbook/assets/SFS Withdrawal Guide Image.png and /dev/null differ diff --git a/.gitbook/assets/SFS Withdrawal Guide.png b/.gitbook/assets/SFS Withdrawal Guide.png deleted file mode 100644 index 39a59ae..0000000 Binary files a/.gitbook/assets/SFS Withdrawal Guide.png and /dev/null differ diff --git a/.gitbook/assets/SFS.png b/.gitbook/assets/SFS.png deleted file mode 100644 index 8279baf..0000000 Binary files a/.gitbook/assets/SFS.png and /dev/null differ diff --git a/SUMMARY.md b/SUMMARY.md index 46a527b..38f7d5e 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -32,18 +32,6 @@ ## Tutorials * [Interacting with Smart Contracts using ethers.js](build-on-mode/interacting-with-smart-contracts-using-ethers.js.md) -* [SFS - Sequencer Fee Sharing](build-on-mode/sfs-sequencer-fee-sharing/README.md) - * [Register a Smart Contract](build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/README.md) - * [SFS - Registering a contract with Remix](build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-registering-a-contract-with-remix.md) - * [SFS - Register a Smart Contract with Thirdweb](build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-register-a-smart-contract-with-thirdweb.md) - * [SFS - Register a Smart Contract with Hardhat](build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-register-a-smart-contract-with-hardhat.md) - * [Assign a Smart Contract](build-on-mode/sfs-sequencer-fee-sharing/assign-a-smart-contract/README.md) - * [SFS - Assign a contract to an existing NFT with Hardhat](build-on-mode/sfs-sequencer-fee-sharing/assign-a-smart-contract/sfs-assign-a-contract-to-an-existing-nft-with-hardhat.md) - * [Withdraw from the SFS](build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/README.md) - * [With a wallet](build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/with-a-wallet.md) - * [With a smart contract](build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/with-a-smart-contract.md) - * [Check the SFS registry](build-on-mode/sfs-sequencer-fee-sharing/check-the-sfs-registry.md) - * [SFS FAQ](introduction/sequencer-fee-sharing/faq.md) * [Deploying a Smart Contract](build-on-mode/deploying-a-smart-contract/README.md) * [Using Hardhat](build-on-mode/deploying-a-smart-contract/using-hardhat.md) * [Using Thirdweb](build-on-mode/deploying-a-smart-contract/using-thirdweb.md) diff --git a/build-on-mode/deploying-a-smart-contract/using-foundry.md b/build-on-mode/deploying-a-smart-contract/using-foundry.md index 742b8c1..8009872 100644 --- a/build-on-mode/deploying-a-smart-contract/using-foundry.md +++ b/build-on-mode/deploying-a-smart-contract/using-foundry.md @@ -134,5 +134,3 @@ In the "Contract" tab you'll find your verified contract. Congratulations, you just deployed and verified a contract on Mode Network using Foundry. To learn more about Mode and how to turn your code into a business, join our [Discord](https://discord.gg/modenetworkofficial) and say hello 👋 - -If you want the next challenge, you can try registering a contract for the SFS following this guide: [sfs-registering-a-contract-with-remix.md](../sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-registering-a-contract-with-remix.md "mention")\ diff --git a/build-on-mode/deploying-a-smart-contract/using-hardhat.md b/build-on-mode/deploying-a-smart-contract/using-hardhat.md index 0286001..3124eac 100644 --- a/build-on-mode/deploying-a-smart-contract/using-hardhat.md +++ b/build-on-mode/deploying-a-smart-contract/using-hardhat.md @@ -178,6 +178,3 @@ Input the contract address from the console to view its details. Congratulations! You've successfully deployed a smart contract on the Mode Testnet using Hardhat and TypeScript.\ \ To learn more about Mode and how to turn your code into a business, join our [Discord](https://discord.gg/modenetworkofficial) and say hello 👋 - -If you want the next challenge, you can try registering a contract for the SFS following this guide: [sfs-registering-a-contract-with-remix.md](../sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-registering-a-contract-with-remix.md "mention")\ -\ diff --git a/build-on-mode/deploying-a-smart-contract/using-remix.md b/build-on-mode/deploying-a-smart-contract/using-remix.md index 9bbff6f..538e22d 100644 --- a/build-on-mode/deploying-a-smart-contract/using-remix.md +++ b/build-on-mode/deploying-a-smart-contract/using-remix.md @@ -107,7 +107,3 @@ Notice that if you call one of the smart contract methods in Remix, you should s In this tutorial, we also went through the Mode bridge, block explorer, and how to interact with your contract. To learn more about Mode and how to turn your code into a business, join our [Discord](https://discord.gg/modenetworkofficial) and say hello 👋 - -If you want the next challenge, you can try registering a contract for the SFS following this guide: [sfs-registering-a-contract-with-remix.md](../sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-registering-a-contract-with-remix.md "mention") - -\ diff --git a/build-on-mode/deploying-a-smart-contract/using-thirdweb.md b/build-on-mode/deploying-a-smart-contract/using-thirdweb.md index 518015a..96b144e 100644 --- a/build-on-mode/deploying-a-smart-contract/using-thirdweb.md +++ b/build-on-mode/deploying-a-smart-contract/using-thirdweb.md @@ -110,6 +110,3 @@ One of the features we liked the most was the “Build” tab in your smart cont
Congratulations! Now you have created and deployed a smart contract on Mode using the Thirdweb CLI. To learn more about Mode and how to turn your code into a business, join our [Discord](https://discord.gg/modenetworkofficial) and say hello 👋 - -If you want the next challenge, you can try registering a contract for the SFS following this guide: [sfs-registering-a-contract-with-remix.md](../sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-registering-a-contract-with-remix.md "mention")\ -\ diff --git a/build-on-mode/sfs-sequencer-fee-sharing/README.md b/build-on-mode/sfs-sequencer-fee-sharing/README.md deleted file mode 100644 index 4673e27..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/README.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -description: Intro to the Sequencer Fee Sharing -hidden: true -noIndex: true ---- - -# SFS - Sequencer Fee Sharing - -When building a layer 2 with the OP stack, block production is primarily managed by a single party, called the sequencer, which helps the network by providing the following services: - -* Providing transaction confirmations and state updates -* Constructing and executing L2 blocks -* Submitting user transactions to L1\ - \ - Until fault proofs are implemented in the OP ecosystem these sequencers are centralized for security and managed by Mode (as every other OP chain) and that’s why Mode benefits from all the sequencer fees generated. That’s where the SFS comes in, giving part of these fees and sharing them with developers that deploy smart contracts. - -{% hint style="success" %} -Developers can earn a share of the network sequencer fees just by registering their contracts in the Fee Sharing Contract.\ -\ -You have to add logic to your smart contract in order to register it in the SFS -{% endhint %} - -\ -The Sequencer Fee Sharing (SFS) contract acts as a registry where all the balances are tracked and stored. Once you deploy your contract and register it in the SFS, you will instantly start earning fees whenever your contract is used.\ -\ -When you register your contract, the SFS mints an NFT as a claim to the earned fees. This NFT is sent to the **`_recipient`** that you specify when calling the register function. The SFS NFT allows anyone who possesses it to claim the rewards for that particular smart contract. Whether the NFT is in your wallet or a smart contract, whatever entity tries to withdraw the earnings needs to hold the NFT in order to withdraw funds. diff --git a/build-on-mode/sfs-sequencer-fee-sharing/assign-a-smart-contract/README.md b/build-on-mode/sfs-sequencer-fee-sharing/assign-a-smart-contract/README.md deleted file mode 100644 index 3cf57aa..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/assign-a-smart-contract/README.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -description: Learn to assign a smart contract to an existing SFS NFT ---- - -# Assign a Smart Contract - -Assigning a contract to the SFS means linking your smart contract to an already existing SFS NFT. This also means that the revenue generated by that smart contract can be claimed with this NFT. - -When you assign a contract there is no NFT being minted. This is useful when dApps have more than one smart contract then you can just register one contract to create the SFS NFT and assign the rest of the contracts to one SFS NFT. By doing this, you will have all the revenue from those contracts accumulated on one NFT. - -Several contracts can be assigned to the same SFS NFT - -Every contract can only be assigned to one SFS NFT - -This is the code of the assign function: - -{% code fullWidth="true" %} -```solidity - /// @notice Assigns smart contract to existing NFT. That NFT will collect fees generated by the smart contract. - /// Callable only by smart contract itself. - /// @param _tokenId tokenId which will collect fees - /// @return tokenId of the ownership NFT that collects fees - function assign(uint256 _tokenId) public onlyUnregistered returns (uint256) { - address smartContract = msg.sender; - - - if (!_exists(_tokenId)) revert InvalidTokenId(); - - - emit Assign(smartContract, _tokenId); - - - feeRecipient[smartContract] = NftData({ - tokenId: _tokenId, - registered: true, - balanceUpdatedBlock: block.number - }); - - - return _tokenId; - } -``` -{% endcode %} - -Here are a few things to note: - -1. The assign function needs to be called by a smart contract and not an EOA. It’s the same as the register function at this point. -2. The assign function does not mint an ownership NFT, rather, it assigns your smart contract to an existing SFS NFT -3. You can assign a contract to an SFS NFT and then change it to another one. diff --git a/build-on-mode/sfs-sequencer-fee-sharing/assign-a-smart-contract/sfs-assign-a-contract-to-an-existing-nft-with-hardhat.md b/build-on-mode/sfs-sequencer-fee-sharing/assign-a-smart-contract/sfs-assign-a-contract-to-an-existing-nft-with-hardhat.md deleted file mode 100644 index 508bb27..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/assign-a-smart-contract/sfs-assign-a-contract-to-an-existing-nft-with-hardhat.md +++ /dev/null @@ -1,220 +0,0 @@ -# SFS - Assign a contract to an existing NFT with Hardhat - -Hardhat is an Ethereum development environment offering tools for smart contract development, and deployment. It supports Solidity, features a testing framework, and allows task automation. With a modular architecture and extensive plugin support, - -In this tutorial, you’ll learn how to register our smart contract to the [Mode SFS contract](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6) by assigning our contract to an existing SFS NFT. - -### Prerequisites - -Before you continue with this tutorial you should have: - -* [npm](https://www.npmjs.com/) and [node.js](https://nodejs.org/en) installed. -* Ethereum wallet preferably [Metamask](https://metamask.io/) Installed. -* Basic understanding of [Solidity](https://soliditylang.org/). -* Sepolia Eth with Mode Network. -* An SFS NFT token Id. - -### What is SFS(Sequencer fee sharing) - -Mode’s SFS is one of the primary features of the Mode network, it lets developers get some percentage of the transaction fees from their contracts' activities on the Mode network. For this to work, your smart contract has to be registered to Mode’s SFS contract. Once registered, you get an ERC 721 NFT (Non-Fungible Token) which allows you to claim your share of the transaction fees generated from your contract. - -The SFS NFT is transferable and can be used to claim rewards for more than one contract, so you can either get a new NFT for multiple smart contracts deployed on Mode, or you can assign multiple smart contracts to an already existing SFS NFT; which is what we’ll be learning about in this tutorial. - -You can explore the full SFS contract code [here](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=contract). - -### Assigning smart contract to an existing SFS NFT - -Let’s take a look at the assign function in the SFS contract to understand how the assigning works. - -Note that this is only a portion of the SFS contract, [check here](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=contract) to see the complete code. - - - -```solidity -function assign(uint256 _tokenId) public onlyUnregistered returns (uint256) { - address smartContract = msg.sender; - - - if (!_exists(_tokenId)) revert InvalidTokenId(); - - - emit Assign(smartContract, _tokenId); - - - feeRecipient[smartContract] = NftData({ - tokenId: _tokenId, - registered: true, - balanceUpdatedBlock: block.number - }); - - - return _tokenId; - } -``` - -This function receives \_tokenId as an input param. It then checks if the tokenId is valid before emitting an Assign event, after which the msg.sender (our smart contract) will be assigned to the tokenId in the SFS, updating the feeRecipient mapping with relevant information. - -Here are a few things to note; - -* The assign function is specified public, meaning an external smart contract can call it. -* The msg.sender is assumed to be a smart contract address because this function is expected to be called by a smart contract. -* The assign function does not mint an ownership NFT, rather, it assigns your smart contract to an existing SFS NFT. -* Assigning a smart contract to an SFS NFT can only be done once. - -\ -Now that we’ve understood how the assign function works, let’s set up our project and build our smart contract.\ - - -### 1. Setting up our project - -Open your terminal to create a new directory for your project. - -`mkdir hardhat` - -Navigate into your project - -`cd hardhat` - -Initialize an npm project - This creates your package.json file. - -`npm init -y` - -Install hardhat - -`npm install --save-dev hardhat` - -To create your project run - -`npx hardhat init` - -When prompted make these selections; - -* Choose "Create a TypeScript project". -* For the .gitignore prompt, select "Yes" (or y). -* Select "Yes" (or y) to install the project's dependencies. - -\ -![](https://lh7-us.googleusercontent.com/\_cX-4P8nGSKmwakBNlASWnGGdiQurBbrQqEC7yrEhhAgpa69gxCTXbWq0wK5HbsbX\_NaXlPMZTy7R7cRW2EUfBtkF1GDKg3iGotPfsW2BwcFS0Q7oA7DyQQ5lRHSiv2aBNIgm\_iS0FVaTN3vhfBInEg) - -### 2. Writing our smart contract - -Head over to the contracts folder of your project, for the sake of this tutorial we will be making use of the Lock contract provided by Hardhat, and we’ll be making some modifications to it. - -First, we added the SFS contract to our file with a register function. Then in the constructor, we invoked the assign function by initializing a new instance of our SFS contract and calling the assign method on it. - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.9; - - -//Here we created our SFS contract -contract SFS { - function assign(uint256 _tokenId) public returns (uint256) {} -} - - -contract Lock { - uint public unlockTime; - address payable public owner; - event Withdrawal(uint amount, uint when); - - - constructor(uint _unlockTime) payable { - require( - block.timestamp < _unlockTime, - "Unlock time should be in the future" - ); - unlockTime = _unlockTime; - owner = payable(msg.sender); - // Initialize an instance of the SFS contract - // Note: Here we passed in the testnet SFS contact address as param - SFS sfsContract = SFS(0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6); - // Call the assign function with our NFT token Id as param - // I used 45 as our token Id, you should change it your own token ID - sfsContract.assign(45); - } - - - function withdraw() public { - require(block.timestamp >= unlockTime, "You can't withdraw yet"); - require(msg.sender == owner, "You aren't the owner"); - emit Withdrawal(address(this).balance, block.timestamp); - owner.transfer(address(this).balance); - } -} -``` - -Mode SFS contact has a different address for Mainnet and Testnet and for this tutorial, we’re deploying to Testnet so we’re going to register to the Testnet’s SFS contract. - -Mainnet SFS Address:[ 0x8680CEaBcb9b56913c519c069Add6Bc3494B7020](https://explorer.mode.network/address/0x8680CEaBcb9b56913c519c069Add6Bc3494B7020?tab=txs) - -Testnet SFS Address:[ 0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6) - -### 3. Configuring harhat for Mode - -Head to the hardhat.config.ts file and replace it with this code to set Mode Network Testnet. Remember to change the account's value to your Metamask private key. - -```tsconfig -import { HardhatUserConfig } from "hardhat/config"; -import "@nomicfoundation/hardhat-toolbox"; - - -const config: HardhatUserConfig = { - networks: { - mode: { - url: "https://sepolia.mode.network", - chainId: 919, - accounts: ["YOUR_METAMASK_PRIVATE_KEY_HERE"] //DO NOT PUSH THIS TO GITHUB - } - }, - solidity: "0.8.9", -}; - - -export default config; -``` - -{% hint style="info" %} -For deploying on Mainnet replace the url and chainId to: - -url: [https://mainnet.mode.network/](https://mainnet.mode.network/) - -chainId: 34443 -{% endhint %} - - - -### 4. Compiling our smart contract - -To compile the smart contract run - -**npx hardhat compile** - -It would return; - -**Successfully generated 8 typings!** - -**Compiled 1 Solidity file successfully (evm target: london).** - -### 5. Deploying - -To deploy we will make use of the deploy.ts file in the scripts folder, we won’t be changing anything because we didn’t change our smart contract. - -To deploy the smart contract to Mode Testnet run - -**npx hardhat run scripts/deploy.ts --network mode** - -It returns - -**Lock with 0.001ETH and unlock timestamp 1702421602 deployed to 0x6900B6158C1BD0C61G1E6a191B1f822EA000E2e8** - -Congratulations! You just deployed and registered your contract with Hardhat and Typescript. - -### Check the Explorer - -To view your transaction head to [Mode Testnet](https://sepolia.explorer.mode.network/) and paste the contract address. - -Your contract should be assigned to the NFT tokenId. To verify if you assigned your contract correctly, you can check our [“Check the registry”](https://docs.mode.network/build-on-mode/tutorials/sfs-sequencer-fee-sharing/sfs-check-the-registry) guide.\ -To import the NFT to your wallet, check our [Adding the SFS NFT to your wallet](https://docs.mode.network/build-on-mode/tutorials/sfs-sequencer-fee-sharing/sfs-check-the-registry#adding-the-sfs-nft-to-your-wallet) tutorial.\ - - diff --git a/build-on-mode/sfs-sequencer-fee-sharing/check-the-sfs-registry.md b/build-on-mode/sfs-sequencer-fee-sharing/check-the-sfs-registry.md deleted file mode 100644 index 6250f61..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/check-the-sfs-registry.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -description: >- - This is a tutorial on how to check the SFS registry to see if you correctly - registered your smart contract ---- - -# Check the SFS registry - -When registering a smart contract in the [SFS (Sequencer Fee Sharing) contract](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=txs) an NFT gets minted to the `_receiver` address that enables that wallet to claim the corresponding fees. - -In this tutorial, we will cover two potential checks: - -1. Check if your wallet has the NFT minted during the registry -2. Check if the contract is registered in the SFS contract-= - -If it’s your first time registering a contract and you don't see the NFT, you may need to add the new token to your wallet. For this, you will need the SFS contract address and the number of the token minted when registering the contract. - -### Adding the SFS NFT to your wallet - -Go to blockscout and look for the transaction that registered your smart contract. - -This is an example one on testnet:\ -\ -[https://sepolia.explorer.mode.network/tx/0x233e46178a8bc1bf7497b2b73591eb8d7f1dbcb33b6263b817c3777ad4041b6b](https://sepolia.explorer.mode.network/tx/0x233e46178a8bc1bf7497b2b73591eb8d7f1dbcb33b6263b817c3777ad4041b6b) - -

Example transaction showing the register transaction

- -In the register transaction you will find the token ID (see screenshot above). You can also find this value as the output of the register function of the SFS. - -With the SFS contract address and the token ID, you can add the NFT to our wallet to see it. \ - - -
- -If you can see the NFT in your wallet, most probably the register was done successfully! You can already use this wallet to claim rewards, if any are available. - -### Checking the SFS registry - -The SFS smart contract keeps track of all the registered smart contracts. You can always go and check if any smart contract is registered or not. - -To do this go to the [SFS contract in blockscout](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=read\_contract). You should go to the “Contract” tab and inside go to the “Read contract” tab. - -Look for the `isRegistered` function. Paste the contract address of your smart contract in the field, in my case, it’s `0xcc9c90501678de6E0c6340E702e0482E95516eac`. Click on Query and see the response you get below.\ -\ -If it says “true” it means that smart contract is registered! - -
- -That's all you need to know on how to check if a smart contract is registered in the SFS. - -To learn more about Mode and how to turn your code into a business, join our [Discord](https://discord.gg/modenetworkofficial) and say hello 👋 diff --git a/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/README.md b/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/README.md deleted file mode 100644 index ff000be..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/README.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -description: Learn to register a smart contract to the SFS ---- - -# Register a Smart Contract - -Registering a contract in the SFS means calling the `register` function defined in the SFS contract and getting an SFS NFT in exchange. The call to the register function must be made from your smart contract. This means you will have to add some code and logic to your contract in order to register it to the SFS. You’ll find code to do this later on this guide. - -This is the register function from the SFS: - -{% code lineNumbers="true" fullWidth="true" %} -```solidity - ///@notice Mints ownership NFT that allows the owner to collect fees earned by the smart contract. - ///`msg.sender` is assumed to be a smart contract that earns fees. Only smart ///contract itself can register a fee receipient. - /// @param _recipient recipient of the ownership NFT - /// @return tokenId of the ownership NFT that collects fees - function register(address _recipient) public onlyUnregistered returns (uint256 tokenId) { - address smartContract = msg.sender; - - if (_recipient == address(0)) revert InvalidRecipient(); - - tokenId = _tokenIdTracker.current(); - _mint(_recipient, tokenId); - _tokenIdTracker.increment(); - - emit Register(smartContract, _recipient, tokenId); - - feeRecipient[smartContract] = NftData({ - tokenId: tokenId, - registered: true, - balanceUpdatedBlock: block.number - }); - } -``` -{% endcode %} - -There are 2 interesting things to note from the register function: - -1. The register function receives (`address`` ``_recipient`) as a parameter. This is the address where the NFT will be minted to. -2. The SFS contract looks at the `msg.sender` in order to know what smart contract is being registered. This is why you need to call the register function from the contract you want to register. **You can only do this once per contract.** diff --git a/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-register-a-smart-contract-with-hardhat.md b/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-register-a-smart-contract-with-hardhat.md deleted file mode 100644 index 27040af..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-register-a-smart-contract-with-hardhat.md +++ /dev/null @@ -1,211 +0,0 @@ -# SFS - Register a Smart Contract with Hardhat - -[Hardhat](https://hardhat.org/) is an Ethereum development framework for creating, testing, and deploying smart contracts. It includes a suite of tools that aid in developing smart contracts and managing the complete development process, allowing developers to write scripts, compile, test, and deploy efficiently. - -In this tutorial, you will learn how to register a smart contract to Mode Network’s SFS (Sequencer Fee Sharing) Contract with Hardhat. - -## Prerequisites - -Before you continue with this tutorial you should: - -* Have [npm](https://www.npmjs.com/) and [node.js](https://nodejs.org/en) installed with the recommended versions. -* Have an Ethereum wallet preferably [Metamask](https://metamask.io/) Installed. -* Have a basic understanding of [Solidity](https://soliditylang.org/). -* [Bridge](https://docs.mode.network/mode-testnet/bridging-to-mode-testnet) Sepolia Eth with Mode Network [bridging-to-mode-testnet.md](../../../user-guides/bridge/bridging-to-mode-testnet.md "mention") - -{% hint style="success" %} -If you want to jump straight to the code, go [here](sfs-register-a-smart-contract-with-hardhat.md#id-2.-writing-our-smart-contract) -{% endhint %} - -## What is Sequencer Fee Sharing (SFS)? - -The SFS contract allows developers to earn a portion of the transaction fees from transactions running on their contract when deployed and registered on Mode Network. The SFS contract implements this functionality and permits other contracts to register and earn. - -To register, your smart contract has to make a call to the SFS contract, after this is done successfully, you will be issued an NFT (Non-Fungible Token). This NFT allows you to claim your fees accumulated in the SFS contract. - - - -## How does the SFS Register function work? - -Let’s look at the SFS contract's register function to understand how the registration works. - -Note that this is only a portion of the SFS contract, [check here](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=contract) to see the complete code. - -```solidity -function register(address _recipient) public onlyUnregistered returns (uint256 tokenId) { - address smartContract = msg.sender; - -// Check if the recipient address is valid; revert if it's null - if (_recipient == address(0)) revert InvalidRecipient(); -// Generate a unique tokenId, mint an NFT to the recipient with it, and update //the tracker - tokenId = _tokenIdTracker.current(); - _mint(_recipient, tokenId); - _tokenIdTracker.increment(); - - emit Register(smartContract, _recipient, tokenId); - -// Update the fee recipient mapping for the smart contract, associating it with //the tokenId and registration details - feeRecipient[smartContract] = NftData({ - tokenId: tokenId, - registered: true, - balanceUpdatedBlock: block.number - }); -} -``` - -This function receives `"_recipient"` as an input and then mints an NFT to this recipient once your smart contract is registered. - -Then, the msg.sender is picked up as the contract to register in the SFS updating the mapping with relevant information.\ - - -**Here are a few things to note:** - -* The Function is specified public meaning an external smart contract can call it. -* The msg.sender is assumed to be a smart contract address, ensuring that a smart contract can register a fee recipient. -* The Function mints an ownership NFT that allows the owner to claim fees earned by the recipient smart contract. - -Now that we’ve understood how the register function works, let’s set up our project. - - - -### 1. Setting Up Our Project - -Open your terminal to create a new directory for your project. - -`mkdir hardhat` - -Navigate into your project - -`cd hardhat` - -Initialize an npm project - This creates your package.json file. - -`npm init -y` - -`Install hardhat` - -`npm install --save-dev hardhat` - -To create your project run - -`npx hardhat init` - -**When prompted make these selections:** - -* Choose "Create a TypeScript project". -* For the .gitignore prompt, select "Yes" (or y). -* For installing the project's dependencies select "Yes" (or y). - -\ - - -
- -### 2. Writing our smart contract - -Head to the contracts folder of your project, for the sake of this tutorial we will be making use of the contract provided by Hardhat. - -Rename the file names lock.sol to any name of your choice then add the register contract to your file and the register function to your constructor.\ - - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.9; -// Add this -contract Register { - function register(address _recipient) public returns (uint256 tokenId) {} -} -// -contract Lock { - uint public unlockTime; - address payable public owner; - event Withdrawal(uint amount, uint when); - - constructor(uint _unlockTime) payable { - require( - block.timestamp < _unlockTime, - "Unlock time should be in the future" - ); - unlockTime = _unlockTime; - owner = payable(msg.sender); - //Add this - Register sfsContract = Register(0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6); - sfsContract.register(msg.sender); // - } - - function withdraw() public { - require(block.timestamp >= unlockTime, "You can't withdraw yet"); - require(msg.sender == owner, "You aren't the owner"); - - emit Withdrawal(address(this).balance, block.timestamp); - - owner.transfer(address(this).balance); - } -}e -``` - -### 3. Configuring Hardhat for Mode - -Head to the hardhat.config.ts file and replace it with this code to set Mode Network Testnet. - -```solidity -import { HardhatUserConfig } from "hardhat/config"; -import "@nomicfoundation/hardhat-toolbox"; - -const config: HardhatUserConfig = { - networks: { - mode: { - url: "https://sepolia.mode.network", - chainId: 919, - accounts: ["YOUR_METAMASK_PRIVATE_KEY_HERE"] //DO NOT PUSH THIS TO GITHUB - } - }, - solidity: "0.8.9", -}; - -export default config; -``` - -### 4. Compiling our contract - -To compile the smart contract run - -`npx hardhat compile` - -It would return; - -`Successfully generated 8 typings!` - -`Compiled 1 Solidity file successfully (evm target: london).` - -{% hint style="danger" %} -It's important that the EVM version is set to london. You might get a "PUSH0" error if you don't set the evm version correctly. You can read more about this issue [here](https://docs.optimism.io/chain/differences). -{% endhint %} - -### 5. Deploying - -To deploy we will make use of the deploy.ts file in the scripts folder, we won’t be changing anything because we didn’t change our smart contract. - -To deploy the smart contract to Mode Testnet run - -`npx hardhat run scripts/deploy.ts --network mode` - -It returns - -`Lock with 0.001ETH and unlock timestamp 1702421602 deployed to 0x6900A6158C1BD0C61F1E6a191B1f822EA000E2e8` - -Congratulations! You just deployed and registered your contract with Hardhat and Typescript. - -## Check the Explorer - -To view your transaction head to [Mode Testnet](https://sepolia.explorer.mode.network/) and paste the contract address. - -Your contract should be registered and your NFT minted. - -To import the NFT to your wallet, check our [Adding the SFS NFT to your wallet](https://docs.mode.network/build-on-mode/tutorials/sfs-sequencer-fee-sharing/sfs-check-the-registry#adding-the-sfs-nft-to-your-wallet) tutorial. - -To learn more about mode and how to turn your code into a business join our Discord and say hi. - - - -To learn more about mode and how to turn your code into a business join our [Discord](https://discord.com/invite/modenetworkofficial) and say hi. diff --git a/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-register-a-smart-contract-with-thirdweb.md b/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-register-a-smart-contract-with-thirdweb.md deleted file mode 100644 index 865554f..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-register-a-smart-contract-with-thirdweb.md +++ /dev/null @@ -1,198 +0,0 @@ -# SFS - Register a Smart Contract with Thirdweb - -[Thirdweb](https://thirdweb.com/) is a web3 platform that provides developers with tools to build, deploy, launch, and manage their applications and games. Some of these tools include pre-built smart contracts, SDKs, and APIs. - -\ -In this tutorial, you will learn how to register a smart contract to Mode Network’s SFS (Sequencer Fee Sharing) Contract while deploying with Thirdweb. - -## Prerequisites - -Before you continue with this tutorial you should: - -* Create a [thirdweb](https://thirdweb.com/) account. -* Have a basic understanding of [Solidity](https://soliditylang.org/). -* [Bridge](https://docs.mode.network/mode-testnet/bridging-to-mode-testnet) Sepolia Eth with Mode Network [bridging-to-mode-testnet.md](../../../user-guides/bridge/bridging-to-mode-testnet.md "mention") -* Have [Node](https://nodejs.org/en) and [Yarn](https://yarnpkg.com/) installed with a recent version. - -{% hint style="success" %} -If you just want to skip to the code go [here](sfs-register-a-smart-contract-with-thirdweb.md#the-register-function-in-practice) -{% endhint %} - -## What is Sequencer Fee Sharing (SFS)? - -Picture this! When you deploy your smart contract to Mode Network, you will be able to receive a percentage of the transaction fees associated with your smart contract. In other words, you get a share of the transaction fees when transactions are made on your contract, rewarding your contribution to the network and incentivizing further innovation and usage of your smart contract. - -But, how does this work? - -You must register your contract with Mode Network's [Registry/SFS contract](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6). When you register, the Registry contract issues you an NFT as a claim to earned fees. The call to register your contract must come from your contract. - -Also, an off-chain component is responsible for processing transactions and calculating your share of fees from each transaction. Your minted NFT allows you to claim your fees accumulated in the SFS contract.\ -\ -One thing to keep in mind is that there would be a two-week time for the fees to accumulate before being transferred to the SFS contract. When this is done you can withdraw your rewards.. - -## How does the SFS Register function work? - -We mentioned earlier that the call to register to the SFS needs to come directly from the smart contract you want to register. To understand how this call works, let’s look at the register function. - -\ -Note that this is only a portion of the SFS contract, [check here](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=contract) to see the complete code. - -```solidity -function register(address _recipient) public onlyUnregistered returns (uint256 tokenId) { - address smartContract = msg.sender; - - -// Check if the recipient address is valid; revert if it's null - if (_recipient == address(0)) revert InvalidRecipient(); - -// Generate a unique tokenId, mint an NFT to the recipient with it, and update //the tracker - tokenId = _tokenIdTracker.current(); - _mint(_recipient, tokenId); - _tokenIdTracker.increment(); - - - emit Register(smartContract, _recipient, tokenId); - - -// Update the fee recipient mapping for the smart contract, associating it with //the tokenId and registration details - feeRecipient[smartContract] = NftData({ - tokenId: tokenId, - registered: true, - balanceUpdatedBlock: block.number - }); -} -``` - -This is a function that receives "\_recipient" as an input and then mints an NFT to this recipient once your smart contract is registered. - -Then, the msg. sender is picked up as the contract to register in the SFS updating the mapping with relevant information. - - - -Here are a few things to note; - -* The Function is specified public meaning an external smart contract can call it. -* The msg.sender is assumed to be a smart contract address, ensuring that a smart contract can register a fee recipient. -* The Function mints an ownership NFT that allows the owner to claim fees earned by the recipient smart contract. - - - -## The Register Function in Practice - -Let's take a look at an example to solidify our understanding; - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; -import "@thirdweb-dev/contracts/base/ERC20Vote.sol"; - - -contract Register { - function register(address _recipient) public returns (uint256 tokenId) {} -} - - -contract Contract is ERC20Vote { - constructor( - address _defaultAdmin, - string memory _name, - string memory _symbol - - ) - ERC20Vote( - _defaultAdmin, - _name, - _symbol - ) - { - Register sfsContract = Register(0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6); - sfsContract.register(msg.sender); - } -} - -``` - -We used a simple ERC20 Vote contract provided with a thirdweb extension which our contract inherits from. - - - -Here are some things to note: - -* Our code defines two contracts the Register and Contract. -* Our contract inherits properties from the ERC20 Vote contract from thirdweb. -* We made an instance of the Register contract and called its register function with the sender’s address ( msg.sender) from the constructor. - -## Deploying Our Contract to Thirdweb - -We will go through the process of installing the CLI, but If you encounter any issues visit the [official documentation](https://portal.thirdweb.com/cli). - -### 1. Download the ThirdWeb CLI - -To install thirdweb globally, open your terminal and run - -\ -`npm i -g thirdweb` - -Now try running: - -`thirdweb --version` - -If the CLI is installed correctly you will be prompted to go to the installed version - -### 2. Create a Local environment - -Create a new project by running - -`npx thirdweb create contract` - -You will be prompted to a menu with different options for setting up your project. For the sake of this tutorial, we will make use of an ERC20 contract. - -However, feel free to select an Empty Contract and write your code from scratch. - -\ - - -
- -### 3. Deploy - -Before deploying, thirdweb requires an API key to monitor your smart contracts, check out this tutorial on creating a [Thirdweb API Key](https://docs.mode.network/build-on-mode/tutorials/deploying-a-smart-contract/using-thirdweb#3.-create-a-thirdweb-api-key) to get it done. - -#### STEP 1 - -Navigate to the root of your project and in a terminal run the following: - -Yarn deploy\ -\ -or\ -\ -`Npx thirdweb deploy` - -You will be directed to your thirdweb dashboard. - -Before Deploying Fill in the parameters for the name and symbol of your token - -Select Mode Testnet as the network of your choice. - -\ - - -
- -#### STEP 2 - -Click on deploy and sign the transaction from your Metamask to complete it. - -\ - - -
- -If everything goes well, you should be prompted with this message ”Success”. - -Congratulations! You just deployed and registered your contract. From your dashboard, you can read your code, monitor events from your contracts, and many more things. - -Our contract should be registered, and the owner address we set as the recipient should have the NFT minted. - -\ -To import the NFT to your wallet, check our [Adding SFS NFT to wallet tutorial.](https://docs.mode.network/build-on-mode/tutorials/sfs-sequencer-fee-sharing/sfs-check-the-registry#adding-the-sfs-nft-to-your-wallet) diff --git a/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-registering-a-contract-with-remix.md b/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-registering-a-contract-with-remix.md deleted file mode 100644 index 3f239de..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/sfs-registering-a-contract-with-remix.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -description: How to register a smart contract on Mode’s SFS register contract. ---- - -# SFS - Registering a contract with Remix - -This tutorial will teach you about the SFS (Sequencer Fee Sharing) contract and how to register a newly deployed contract. - -if you want to go straight to the code examples go to [#sample-smart-contract](sfs-registering-a-contract-with-remix.md#sample-smart-contract "mention"). - -### Introducing SFS (Sequencer Fee Sharing) - -Developers can earn a share of the network Sequencer fees by registering their contracts in the Fee Sharing Contract (based on Canto's Turnstile.sol) deployed at [0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=txs) on Mode testnet. A portion of transaction fees of all transactions involving their smart contract will accumulate in the Fee Sharing Contract. - -When registering your contract, the registry contract issues an NFT as a claim to the earned fees by the recipient specified in the call to register the smart contract. This means your smart contract needs to make the call to the SFS contract in order to register. The minted NFT is transferable and can be used to claim fees for multiple contracts. - -An offchain component will process the transactions for each smart contract to calculate it's share of fees. This component will also distribute the fees to registered smart contracts in the SFS contract. Note that there may be a lockup period on withdrawal of distributed funds for up to 2 weeks.\ -You can see the code of the SFS contract [here](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=contract). If you are a little bit familiar solidity, we would recommend you to take a look at the “register” function. We'll go over it later in this tutorial. - -Now that we know what the SFS registry is, let’s register a sample smart contract to start earning fees. - -### SFS register function review - -Let’s take a quick look at the SFS contract. More specifically, the register function. There are 2 interesting things to note from this function. The first one is that the parameter the function receives (`address`` ``_recipient`) is the address of the recipient of the earned fees. The second one is that, to know what smart contract is being registered, the SFS contract looks at the msg.sender. This is why you need to call this register function from the contract you want to register. You can only register your contract once. - -```sol - /// @notice Mints ownership NFT that allows the owner to collect fees earned by the smart contract. - /// `msg.sender` is assumed to be a smart contract that earns fees. Only smart contract itself - /// can register a fee receipient. - /// @param _recipient recipient of the ownership NFT - /// @return tokenId of the ownership NFT that collects fees - function register(address _recipient) public onlyUnregistered returns (uint256 tokenId) { - address smartContract = msg.sender; - - if (_recipient == address(0)) revert InvalidRecipient(); - - tokenId = _tokenIdTracker.current(); - _mint(_recipient, tokenId); - _tokenIdTracker.increment(); - - emit Register(smartContract, _recipient, tokenId); - - feeRecipient[smartContract] = NftData({ - tokenId: tokenId, - registered: true, - balanceUpdatedBlock: block.number - }); - } -``` - -For this tutorial, we will be using Remix to deploy and interact with the contracts, but you can deploy with any tools you prefer. - -### Sample smart contract - -This is a basic [ERC-20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.0/contracts/token/ERC20/ERC20.sol) token using the [OpenZepellin](https://docs.openzeppelin.com/contracts/4.x/erc20) contract. In the example code snippet below, you will find a Register contract with the signature of the register function following the SFS contract. - -We will be using the tesnet SFS address, but if you want to register a contract on Mainnet, you should change the address on line 19.\ -\ -Mainnet SFS Address: [0x8680CEaBcb9b56913c519c069Add6Bc3494B7020](https://explorer.mode.network/address/0x8680CEaBcb9b56913c519c069Add6Bc3494B7020?tab=txs)\ -Testnet SFS Address: [0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6) - -{% hint style="info" %} -**IMPORTANT:** In order to register your smart contract in the SFS, it’s mandatory to have a call to the register function in your smart contract. This call needs to be made from your contract. -{% endhint %} - -{% code lineNumbers="true" %} -```solidity -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity ^0.8.20; - -import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v5.0.0/contracts/token/ERC20/ERC20.sol"; - - -interface ISFS { - function register(address _recipient) external returns (uint256 tokenId); -} - -contract ModeToken is ERC20 { - - address feeReceiver = msg.sender; - - constructor() ERC20("ModeTokenSFSTest", "SFST2") { - _mint(msg.sender, 1000 * 10 ** 18); //Example amount to mint our ERC20 - feeReceiver = msg.sender; //The deployer of the contract will get the NFTto widthraw the earned fees - ISFS sfsContract = ISFS(0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6); // This address is the address of the SFS contract - sfsContract.register(msg.sender); //Registers this contract and assigns the NFT to the owner of this contract - } -} -``` -{% endcode %} - -In this case, our `constructor()` creates an instance of the Register contract using the SFS contract address passed as an argument and then calls the register function in the SFS contract, passing the `msg.sender` as parameter. - -That’s all we need to add to our smart contract to register it! The contract will register itself on deployment, so let's go do that. - -### Deploying and registering the contract - -We will be using Remix, so we'll go to the deploy tab and use the “Injected Provider - Metamask” to connect Metamask and deploy our contract. Please make sure in the compiler’s tab that the EVM version is set to london or else you'll get a `PUSH0` error message. - -{% hint style="warning" %} -With Remix, is important that you pay attention to which network you are connected. In this case we are using Mode's testnet but the same process applies for Mainnet. -{% endhint %} - - - -After deploying and confirming the transaction in Metamask that’s it! \ -\ -If the transaction was successful, your contract should be registered and your wallet should have the SFS NFT minted. This NFT is the one that allows you to claim your rewards. - -To validate if the registration was done correctly check our [check-the-sfs-registry.md](../check-the-sfs-registry.md "mention") tutorial.\ -\ -To learn more about Mode and how to turn your code into a business, join our [Discord](https://discord.gg/modenetworkofficial) and say hello 👋\ diff --git a/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/README.md b/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/README.md deleted file mode 100644 index e9f7c71..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/README.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -description: In this section you will learn different ways of withdrawing from the SFS. ---- - -# Withdraw from the SFS - -{% hint style="info" %} -There is a minimum to claim the SFS earned fees and it's `0.01 ETH` -{% endhint %} - -There are 3 ways of claiming your funds: - -1. In one click from the [developer dashboard](https://app.mode.network/developers/) (Recommended) -2. Directly from a wallet that holds the NFT -3. Programmatically from a smart contract that should also hold the NFT - -The SFS contract works as a balance sheet. It contains all the mappings tracking which contracts are linked to which SFS NFTs. All balances are kept in the contract, until the users withdraw them.\ -\ -The revenue of the SFS is calculated by an offchain component that distributes the fees at the end of an epoch. You will not see your balance immediately going up after registering your contract because this off-chain component updates the balances every first day of the month on mainnet and every 24 hours on testnet. - -To withdraw, you must hold the SFS NFT to be allowed to get the revenue. If not, the transaction will revert. It doesn’t matter if it’s an EOA (Externally Owned Account) or a smart contract, any of them must have the NFT in their balance in order to withdraw the funds.\ -\ -This is the withdrawal function: - -{% code fullWidth="true" %} -```solidity - /// @notice Withdraws earned fees to `_recipient` address. Only callable by NFT owner. - /// @param _tokenId token Id - /// @param _recipient recipient of fees - /// @param _amount amount of fees to withdraw - /// @return amount of fees withdrawn - function withdraw(uint256 _tokenId, address payable _recipient, uint256 _amount) - public - onlyNftOwner(_tokenId) - returns (uint256) - { - uint256 earnedFees = balances[_tokenId]; - - if (earnedFees == 0 || _amount == 0) revert NothingToWithdraw(); - if (_amount > earnedFees) _amount = earnedFees; - - balances[_tokenId] = earnedFees - _amount; - - emit Withdraw(_tokenId, _recipient, _amount); - - Address.sendValue(_recipient, _amount); - - return _amount; - } -``` -{% endcode %} - -Note that the function has the `onlyNftOwner` modifier which reverts the transaction if the entity calling the function is not the owner of the NFT. diff --git a/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/with-a-smart-contract.md b/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/with-a-smart-contract.md deleted file mode 100644 index 54ca0fd..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/with-a-smart-contract.md +++ /dev/null @@ -1,155 +0,0 @@ -# With a smart contract - -## **How To Withdraw funds from Mode SFS programatically.** - -Mode Sequencer Fee Sharing is a feature of Mode Network that enables developers to earn a pecentage of the gas fee spent on every transaction that happens on their smart contract. - -In this tutorial, you’ll learn how to withdraw funds accumulated in your Mode SFS to your wallet programmatically. - -### **Prerequisites** - -Before you continue with this tutorial you should: - -* Have [Metamask](https://metamask.io/) Installed. -* Create a [thirdweb](https://thirdweb.com/) account. -* [Bridge](https://docs.mode.network/mode-testnet/bridging-to-mode-testnet) Sepolia Eth with Mode Network. - -### **How does the SFS Withdraw function work?** - -We mentioned earlier that the call to register to the SFS needs to come directly from the smart contract you want to register. To understand how this call works, let’s look at the register function. - -Note that this is only a portion of the SFS contract, [check here](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=contract) to see the complete code. - -```solidity -function withdraw(uint256 _tokenId, address payable _recipient, uint256 _amount) - public - onlyNftOwner(_tokenId) - returns (uint256) - { - uint256 earnedFees = balances[_tokenId]; - - if (earnedFees == 0 || _amount == 0) revert NothingToWithdraw(); - if (_amount > earnedFees) _amount = earnedFees; - - balances[_tokenId] = earnedFees - _amount; - - emit Withdraw(_tokenId, _recipient, _amount); - - Address.sendValue(_recipient, _amount); - - return _amount; - } -``` - -The withdraw function enables NFT owners to claim their accumulated fees from the smart contract. It takes three parameters: the NFT's unique identifier (\_tokenId), the recipient's wallet address (\_recipient), and the amount to withdraw (\_amount). - -#### Key steps and features include: - -* **Verification**: Ensures that only the NFT owner can initiate the withdrawal, using the onlyNftOwner modifier. -* **Checks**: Confirms there are sufficient earned fees to withdraw and adjusts the withdrawal amount if it exceeds the available balance. -* **Balance Update:** Deducts the withdrawn amount from the NFT's total earned fees. -* **Funds Transfer:** Sends the specified amount to the recipient's address. -* **Logging:** Emits a Withdraw event with transaction details. -* **Return Value:** The function returns the actual amount withdrawn. - -This function offers a secure and straightforward way for users to retrieve their fees directly to their wallets. - -### **The Withdraw Function in Practice** - -Now let’s take a look and an example and put our knowledge to test. - -```solidity -// SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; - -interface ISFS { - function balances(uint256 _tokenId) external view returns (uint256); - function withdraw( - uint256 _tokenId, - address payable _recipient, - uint256 _amount - ) external returns (uint256); -} - -contract Withdraw { - - //existing code - - function callWithdrawOnFeeSharing( - uint256 tokenId, - address recipient, - uint256 amount - ) external { - // Create an instance of the FeeSharingInterface - ISFS feeSharingContract = ISFS( - 0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6 - ); - - // Call the withdraw function - feeSharingContract.withdraw(tokenId, payable(recipient), amount); - } - - function checkSFSBalance() public view returns (uint256) { - // Create an instance of the FeeSharingInterface - ISFS feeSharingContract = ISFS( - 0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6 - ); - - // Call the withdraw function - return feeSharingContract.balances(11); - // Replace 11 with the tokenId of the SFS NFT you want to withdraw from. - } -} -``` - -We added an additional function checkBalance to help us check our balance in the SFS so we can know how to to withdraw. Remember to change the - -#### Here are some things to note: - -* Our code defines an interface of the withdraw and balance function. -* Our contract doesn’t show how to register or assign our contract an SFS NFT because the focus of this tutorial is to withdraw but please bear in my that you can only withdraw from a contract that has being registered and already earned fees. -* We made an instance of the SFS contract and called its withdraw function while passing the tokenId of the NFT with right to the contract we want to withdraw from, the recipient address we want to send the money to and finally the amount we want to send withdraw. - -### **Deploying Our Contract to Thirdweb** - -You can learn in details the step by step guide on how to deploy to Mode using thirdweb from this [article](https://docs.mode.network/build-on-mode/deploying-a-smart-contract/using-thirdweb). - -### **Test** - -After you’re done deploying and you have interacted with you smart contract, head over to the explorer section of your contract on thirdweb and check how much your contract has earned by running the checkBalance function. - -#### Check balance - -
- -Now you’re sure you have a balance and you also get to know how much to withdraw if you don’t withdraw everything. Remember the unit is in Wei. - -#### Withdraw - -Click on the Withdraw function, enter the Token Id, the recipient address and the amount you want to send, in this case I just divided my balance into two. - -Remember that your contract needs to be in possession of the NFT it is trying to claim with, so if you assigned an already existing NFT token id to your contract then you’ll also need to transfer that NFT to the contract you’re interacting with. - -Click on execute! - -
- -It’s going to pop up your wallet and ask you to confirm the transaction. - -### Internal transaction - -If your using MetaMask the contract interaction will show in your wallet activities but the internal transaction won’t show, the transaction that shows up on your MetaMask won’t show the value sent but your wallet balance will update, the balance update can be significant or not depending on the amount you withdraw form the SFS. - -By the way, internal transactions are transactions that are initiated inside code itself, it involves smart contract sending value to a wallet or another smart contract. You can learn more about internal transactions [here](https://support.metamask.io/hc/en-us/articles/360058568312-Internal-transactions) - -You can find the internal transaction by opening the transaction hash on Mode explorer and then clicking the internal tnxs tab - -
- -Here you’ll see the actual transaction and the value sent. You can also click on your wallet address here to see your balance. - -### **Summary** - -In this article we learnt about the SFS Withdraw function and how it works, we also tested that to see it in action. We also learnt about internal transactions and how to view them on Mode explorer. - -To learn more about Mode and how to turn your code into a business, join our [Discord](https://dub.sh/mode-discord) and say hello **👋** diff --git a/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/with-a-wallet.md b/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/with-a-wallet.md deleted file mode 100644 index d13a846..0000000 --- a/build-on-mode/sfs-sequencer-fee-sharing/withdraw-from-the-sfs/with-a-wallet.md +++ /dev/null @@ -1,20 +0,0 @@ -# With a wallet - -To withdraw with a wallet all you have to do is hold the NFT in your wallet and call the withdraw function of the SFS contract directly with your wallet.\ -\ -To do this, you will need these 3 pieces of information: - -* [ ] \_tokenId : This is the ID of your SFS NFT. It's unique and it's incremental by 1 every time someone registers a contract. -* [ ] \_recipient : This is the address to where the earnings will be sent -* [ ] \_amount : this is the amount to withdraw, if you set a higher amount, you will just withdraw the total of the earned fees - -Once you have this, you just have to go to [Testnet Blockscout](https://sepolia.explorer.mode.network/address/0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6?tab=write\_contract) or to [Mainnet Blockscout ](https://explorer.mode.network/address/0x8680CEaBcb9b56913c519c069Add6Bc3494B7020?tab=txs)depending on where your NFT and contracts are delpoyed. - -1. Go to the `Contract` tab and select `Write Contract` -2. Look at the bottom for the `11. withdraw` function -3. Input the toknID, recipient and amount. - - e.g: (203, 0x807CbE33a6F4c0F524C97B2AbcFf919da41cd7Cf, 2342342344) -4. Sign the transaction and wait until you get the rewards! - -
diff --git a/build-on-mode/verifying-your-smart-contract/README.md b/build-on-mode/verifying-your-smart-contract/README.md index 5c1c21e..6356179 100644 --- a/build-on-mode/verifying-your-smart-contract/README.md +++ b/build-on-mode/verifying-your-smart-contract/README.md @@ -2,7 +2,7 @@ Verifying a smart contract involves confirming that the contract's code on the blockchain matches the source code provided by the developer. This process allows all other users to see the source code in clear text that was deployed on chain. \ \ -For example, in our SFS contract you can see it's verified and you can see the code:\ +For example, in this contract you can see it's verified and you can see the code:\ \ [https://explorer.mode.network/address/0x8680CEaBcb9b56913c519c069Add6Bc3494B7020?tab=contract](https://explorer.mode.network/address/0x8680CEaBcb9b56913c519c069Add6Bc3494B7020?tab=contract)\ \ diff --git a/introduction/dev-onboarding-checklist.md b/introduction/dev-onboarding-checklist.md index 1d36ae4..257fb06 100644 --- a/introduction/dev-onboarding-checklist.md +++ b/introduction/dev-onboarding-checklist.md @@ -27,7 +27,6 @@ Follow [this guide](https://mode.hashnode.dev/get-developer-role) on how to get - [ ] Deploy a smart contract on Mode testnet * [ ] [quick-start.md](quick-start.md "mention") * [ ] [deploying-a-smart-contract](../build-on-mode/deploying-a-smart-contract/ "mention") - * [ ] [register-a-smart-contract](../build-on-mode/sfs-sequencer-fee-sharing/register-a-smart-contract/ "mention") * [ ] _**EXTRA:**_[verifying-your-smart-contract](../build-on-mode/verifying-your-smart-contract/ "mention") diff --git a/introduction/quick-start.md b/introduction/quick-start.md index 6b90af0..86bc95b 100644 --- a/introduction/quick-start.md +++ b/introduction/quick-start.md @@ -21,7 +21,7 @@ We are ready to get started! For the sake of this tutorial, we will be deploying the ‘1\_Storage.sol’ smart contract that comes as an example in Remix, but you can use any of your code. -We added a few lines of code to register this contract on the SFS. You can copy and then paste this in Remix or use your own contract code.\ +You can copy and then paste this in Remix or use your own contract code.\ \ Here's the sample code: @@ -31,10 +31,6 @@ Here's the sample code: pragma solidity ^0.8.20; -interface Sfs { - function register(address _recipient) external returns (uint256 tokenId); -} - contract Storage { uint256 number; diff --git a/introduction/sequencer-fee-sharing/faq.md b/introduction/sequencer-fee-sharing/faq.md deleted file mode 100644 index 308776e..0000000 --- a/introduction/sequencer-fee-sharing/faq.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -description: SFS Frequently Asked Questions ---- - -# SFS FAQ - - - -
- -What is Sequencer Fee Sharing (SFS) in Mode Network? - -SFS in Mode Network is a mechanism that allows developers to earn a portion of the network's sequencer fees. By registering their smart contracts with the SFS contract, developers can receive a share of the fees generated from transactions involving their contracts. - -
- -
- -Can an NFT accrue the revenue of more than one contract? - -Yes, with the `assign` function. This function is used to link a smart contract to an existing SFS NFT. This is particularly useful for dApps with multiple contracts, allowing them to accumulate revenue from all contracts under a single NFT, simplifying the fee collection process. - -
- -
- -Is there a minimum to claim the fees? - -Yes, there is a minimum and it's `0.01 ETH` . This way developers can accumulate during more than one epoch until they reach this number. - -
- -
- -Can a contract be registered multiple times in the SFS? - -No, each smart contract can only be registered once in the SFS. This ensures a clear and unambiguous link between a contract and its corresponding NFT for fee collection. - -
- -
- -What is the role of the NFT in SFS? - -In SFS, the NFT functions as a digital certificate, signifying the holder's right to claim fees accrued by a specific smart contract. It's a unique representation of ownership and fee entitlement, linked directly to the contract's activity. - -
- -
- -What is the process to register a contract in the SFS? - -To register a contract in the SFS, developers must call the `register` function from within their smart contract. This action mints an NFT, which serves as a token of ownership and entitlement to the fees generated by the contract's usage. - -
- -
- -How often are fee balances updated in the SFS? - -In the SFS, fee balances are updated every first day of the month on the mainnet and every 24 hours on the testnet. This periodic update reflects the accumulation of fees generated by the registered contracts. - -
- -
- -Who can withdraw earned fees from the SFS? - -Withdrawal of earned fees is restricted to the holder of the SFS NFT linked to the smart contract. This can be either an Externally Owned Account (EOA) or a smart contract, provided they possess the NFT at the time of withdrawal. - -
- -
- -What happens if the withdrawal amount exceeds the earned fees? - -If the requested withdrawal amount exceeds the available earned fees, the system automatically adjusts the withdrawal to the maximum available amount. This ensures that withdrawals are always within the bounds of the actual fees accumulated by the contract. - -
- -
- -What is the difference between registering and assigning in the SFS? - -The key difference between registering and assigning in the Sequencer Fee Sharing (SFS) system lies in the purpose and outcome of each action. - -* **Registering a Contract:** When you register a contract in the SFS, you are essentially initiating its participation in the fee-sharing mechanism. This process involves calling the `register` function from your smart contract, which results in the minting of a unique NFT. This NFT serves as a token of ownership and entitlement to the fees generated by the contract's usage. Registration is a one-time process for each contract, establishing its link to the SFS and enabling it to start accumulating fees. -* **Assigning a Contract:** Assigning, on the other hand, is the process of linking a smart contract to an already existing SFS NFT. This action is performed using the `assign` function and does not involve minting a new NFT. Instead, it allows the fees generated by this contract to be accumulated under the NFT specified in the assignment. This is particularly useful for developers who manage multiple contracts and wish to consolidate their fee earnings under a single NFT, simplifying the management and collection of fees. - -
- -## - - - -## - - - -If you have a question we haven't addressed, please let us know in our [Discord](https://discord.gg/modenetworkofficial). diff --git a/user-guides/mainnet-contract-addresses/README.md b/user-guides/mainnet-contract-addresses/README.md index bb1a344..7ef8313 100644 --- a/user-guides/mainnet-contract-addresses/README.md +++ b/user-guides/mainnet-contract-addresses/README.md @@ -6,7 +6,7 @@ description: Addresses to the main contract addresses In this section you will find useful contract addresses you may need while developing on Mode. \ \ -L1/L2 Contracts are the main contacts from the L1 (Ethereum) and the L2 (Mode) such as the SFS contract, L1Standard Bridge, and more. +L1/L2 Contracts are the main contacts from the L1 (Ethereum) and the L2 (Mode) such as the L1Standard Bridge, and more. Token Addresses has all the official tokens deployed by Mode team, please be careful with other tokens not listed here as they may not be legitimate. diff --git a/user-guides/mainnet-contract-addresses/l1-l2-contracts.md b/user-guides/mainnet-contract-addresses/l1-l2-contracts.md index 17cb14c..f2188db 100644 --- a/user-guides/mainnet-contract-addresses/l1-l2-contracts.md +++ b/user-guides/mainnet-contract-addresses/l1-l2-contracts.md @@ -11,7 +11,6 @@ These are Mainnet contract addresses. If you want to add a missing one please su | Name | Address | | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | $MODE Staking Contract | [0x74B847b308BD89Ef15639E6e4a2544E4b8b8C6B4](https://explorer.mode.network/address/0x74B847b308BD89Ef15639E6e4a2544E4b8b8C6B4?tab=tokens) | -| SFS Contract | [0x8680CEaBcb9b56913c519c069Add6Bc3494B7020](https://explorer.mode.network/address/0x8680CEaBcb9b56913c519c069Add6Bc3494B7020?tab=txs) | | Pyth Oracle contract | [0xA2aa501b19aff244D90cc15a4Cf739D2725B5729](https://explorer.mode.network/address/0xA2aa501b19aff244D90cc15a4Cf739D2725B5729) | | Supra Pull Oracle contract | [0x2FA6DbFe4291136Cf272E1A3294362b6651e8517](https://explorer.mode.network/address/0x2FA6DbFe4291136Cf272E1A3294362b6651e8517?tab=contract) | | Redstone Oracles Price Feeds | [0x7C1DAAE7BB0688C9bfE3A918A4224041c7177256](https://explorer.mode.network/address/0x7C1DAAE7BB0688C9bfE3A918A4224041c7177256?tab=txs) | diff --git a/user-guides/mainnet-contract-addresses/testnet-contract-addresses.md b/user-guides/mainnet-contract-addresses/testnet-contract-addresses.md index 1879f29..535c2e2 100644 --- a/user-guides/mainnet-contract-addresses/testnet-contract-addresses.md +++ b/user-guides/mainnet-contract-addresses/testnet-contract-addresses.md @@ -8,7 +8,7 @@ description: >- ## Ethereum **Sepolia Testnet and Mode Testnet Contract Addresses** -
Name Address
$MODE testnet token0x4FFa6cDEB4deF980b75e3F4764797A2CAd1fAEF3
Pyth Oracle Price Feed0xA2aa501b19aff244D90cc15a4Cf739D2725B5729
SFS Contract0xBBd707815a7F7eb6897C7686274AFabd7B579Ff6
Proxy__OVM_L1StandardBridge0xbC5C679879B2965296756CD959C3C739769995E2
L2StandardBridge0x4200000000000000000000000000000000000010
L1ERC721Bridge0x7Bf471d9181AD783c7510243D1B0EBc6f29e9a81
SystemDictator0x92fE7f11452D8fff92ebfFb47036e0443ea110F1
PortalSender0xd1b3CBdB812712d71F5440Af34bf605b34b6c21C
L1StandardBridge0x98C41994F0b4DcCD52fad6BfeA6615de34C2ce0f
Lib_AddressManager0x83D45725d6562d8CD717673D6bb4c67C07dC1905
L2OutputOracleProxy0x2634BD65ba27AB63811c74A63118ACb312701Bfa
OptimismMintableERC20FactoryProxy0x00F7ab8c72D32f55cFf15e8901C2F9f2BF29A3C0
Proxy__OVM_L1StandardBridge0xbC5C679879B2965296756CD959C3C739769995E2
ProxyAdmin0xE7413127F29E050Df65ac3FC9335F85bB10091AE
OptimismMintableERC20Factory0x0f5908861962DfFaB7e4d9a1c9F513F1988E8dCC
OptimismPortal0xd9B9DCE20d7837379cbD4Fa1a58Bc70E595bb9a5
Proxy__OVM_L1CrossDomainMessenger0xc19a60d9E8C27B9A43527c3283B4dd8eDC8bE15C
L1ERC721BridgeProxy0x015a8c2e0a5fEd579dbb05fd290e413Adc6FC24A
SystemConfig0x2238382DCEA03f024993c8a0355917c80B20301F
OptimismPortalProxy0x320e1580effF37E008F1C92700d1eBa47c1B23fD
L1CrossDomainMessenger0x9B800c1e8b61Aa9D141BCD317dDe7849F7A043E5
L2OutputOracle0xEeBD920aE8444C4F5d6aD07879cCBeb53663d93A
SystemDictatorProxy0x20c608922171A06A7bC5448acf6197fEE7448a8b
SystemConfigProxy0x15cd4f6e0CE3B4832B33cB9c6f6Fe6fc246754c2
+
Name Address
$MODE testnet token0x4FFa6cDEB4deF980b75e3F4764797A2CAd1fAEF3
Pyth Oracle Price Feed0xA2aa501b19aff244D90cc15a4Cf739D2725B5729
Proxy__OVM_L1StandardBridge0xbC5C679879B2965296756CD959C3C739769995E2
L2StandardBridge0x4200000000000000000000000000000000000010
L1ERC721Bridge0x7Bf471d9181AD783c7510243D1B0EBc6f29e9a81
SystemDictator0x92fE7f11452D8fff92ebfFb47036e0443ea110F1
PortalSender0xd1b3CBdB812712d71F5440Af34bf605b34b6c21C
L1StandardBridge0x98C41994F0b4DcCD52fad6BfeA6615de34C2ce0f
Lib_AddressManager0x83D45725d6562d8CD717673D6bb4c67C07dC1905
L2OutputOracleProxy0x2634BD65ba27AB63811c74A63118ACb312701Bfa
OptimismMintableERC20FactoryProxy0x00F7ab8c72D32f55cFf15e8901C2F9f2BF29A3C0
Proxy__OVM_L1StandardBridge0xbC5C679879B2965296756CD959C3C739769995E2
ProxyAdmin0xE7413127F29E050Df65ac3FC9335F85bB10091AE
OptimismMintableERC20Factory0x0f5908861962DfFaB7e4d9a1c9F513F1988E8dCC
OptimismPortal0xd9B9DCE20d7837379cbD4Fa1a58Bc70E595bb9a5
Proxy__OVM_L1CrossDomainMessenger0xc19a60d9E8C27B9A43527c3283B4dd8eDC8bE15C
L1ERC721BridgeProxy0x015a8c2e0a5fEd579dbb05fd290e413Adc6FC24A
SystemConfig0x2238382DCEA03f024993c8a0355917c80B20301F
OptimismPortalProxy0x320e1580effF37E008F1C92700d1eBa47c1B23fD
L1CrossDomainMessenger0x9B800c1e8b61Aa9D141BCD317dDe7849F7A043E5
L2OutputOracle0xEeBD920aE8444C4F5d6aD07879cCBeb53663d93A
SystemDictatorProxy0x20c608922171A06A7bC5448acf6197fEE7448a8b
SystemConfigProxy0x15cd4f6e0CE3B4832B33cB9c6f6Fe6fc246754c2
## **Uniswap V3 Contract Addresses**