### Setup Plume Contracts with Foundry Source: https://github.com/plumenetwork/contracts/blob/main/smart-wallets/README.md Installs the Foundry toolchain and necessary dependencies for developing Plume smart contracts. Assumes Foundry is not already installed. ```bash $ foundryup $ forge install ``` -------------------------------- ### Static Analysis of Plume Contracts with Slither Source: https://github.com/plumenetwork/contracts/blob/main/smart-wallets/README.md Performs static analysis on the Plume smart contracts to identify potential vulnerabilities and issues. Requires Slither to be installed and a configuration file. ```bash # Get list of issues $ slither --config-file slither.config.json . ``` -------------------------------- ### Install Forge Standard Library Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/README.md Command to install the Forge Standard Library using the Forge package manager. This is a prerequisite for using its features in your Foundry projects. ```bash forge install foundry-rs/forge-std ``` -------------------------------- ### Plume Launch Steps for Spin and Raffle Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Solidity code snippets demonstrating the launch process for Spin and Raffle contracts. This includes configuring prizes, setting campaign start dates, and enabling the Spin functionality. ```solidity // 1. Configure Raffle Prizes raffle.addPrize(prizeId, prizeDetails); // 2. Set Campaign Start Date (Spin) spin.setCampaignStartDate(startTimestamp); // 3. Enable Spin spin.setEnabledSpin(true); ``` -------------------------------- ### Compile Plume Smart Contracts using Foundry Source: https://github.com/plumenetwork/contracts/blob/main/smart-wallets/README.md Compiles all the smart contracts within the Plume project using the Foundry's forge compiler. This step is essential before testing or deploying. ```bash $ forge compile ``` -------------------------------- ### Test and Analyze Plume Contracts with Foundry Source: https://github.com/plumenetwork/contracts/blob/main/smart-wallets/README.md Executes all defined tests for the Plume smart contracts and generates a code coverage report. The `--ir-minimum` flag optimizes the coverage report for faster generation. ```bash $ forge test $ forge coverage --ir-minimum ``` -------------------------------- ### Reward Calculation System: Checkpoint Creation Example Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md JavaScript code illustrating the creation of rate and commission checkpoints based on a simulated timeline. This demonstrates how changes in reward rates and commission percentages are recorded for accurate historical calculations. ```javascript // Reward Rate Checkpoints Checkpoint 0: { timestamp: Jan 5, rate: 100e18, // 100 tokens/day/staked token cumulativeIndex: 0 } Checkpoint 1: { timestamp: Jan 15, rate: 150e18, cumulativeIndex: 1000e18 // Accumulated from previous segment } // Commission Checkpoints Checkpoint 0: { timestamp: Jan 5, rate: 0.1e18 } // 10% Checkpoint 1: { timestamp: Jan 15, rate: 0.15e18 } // 15% Checkpoint 2: { timestamp: Jan 25, rate: 0.2e18 } // 20% ``` -------------------------------- ### Deploy Plume Smart Wallet Contract with Foundry Source: https://github.com/plumenetwork/contracts/blob/main/smart-wallets/README.md Deploys the Smart Wallet contract using Foundry's scripting capabilities. It includes options for verification against Blockscout and legacy transaction format. ```bash $ forge script script/DeploySmartWallet.s.sol --rpc-url $RPC_URL --broadcast \ --verify --verifier blockscout --verifier-url $VERIFIER_URL -g 500 --legacy ``` -------------------------------- ### Reward Calculation System: Detailed Calculation Example Flowchart Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md A flowchart visualizing the detailed calculation process for rewards, starting from a user staking PLUME, through various rate and commission changes, to the final reward claim. It visually breaks down the segments and events affecting reward accrual. ```mermaid flowchart LR A[Jan 1
Stake 1000] --> B[Jan 5
Rate: 100/day
Comm: 10%] B --> C[Jan 15
Rate: 150/day
Comm: 15%] C --> D[Jan 25
Comm: 20%
Rate unchanged] D --> E[Jan 30
Claim] style A fill:#e1f5fe style E fill:#c8e6c9 ``` -------------------------------- ### Forge Stdlib: Test Storage Slots and Values in Solidity Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/README.md This example demonstrates how to use Forge's stdlib to interact with contract storage. It covers finding storage slots for public variables, mappings, structs, and hidden variables, as well as writing new values to these slots. It requires the Forge testing environment. ```solidity import "forge-std/Test.sol"; contract TestContract is Test { using stdStorage for StdStorage; Storage test; function setUp() public { test = new Storage(); } function testFindExists() public { // Lets say we want to find the slot for the public // variable `exists`. We just pass in the function selector // to the `find` command uint256 slot = stdstore.target(address(test)).sig("exists()").find(); assertEq(slot, 0); } function testWriteExists() public { // Lets say we want to write to the slot for the public // variable `exists`. We just pass in the function selector // to the `checked_write` command stdstore.target(address(test)).sig("exists()").checked_write(100); assertEq(test.exists(), 100); } // It supports arbitrary storage layouts, like assembly based storage locations function testFindHidden() public { // `hidden` is a random hash of a bytes, iteration through slots would // not find it. Our mechanism does // Also, you can use the selector instead of a string uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find(); assertEq(slot, uint256(keccak256("my.random.var"))); } // If targeting a mapping, you have to pass in the keys necessary to perform the find // i.e.: function testFindMapping() public { uint256 slot = stdstore .target(address(test)) .sig(test.map_addr.selector) .with_key(address(this)) .find(); // in the `Storage` constructor, we wrote that this address' value was 1 in the map // so when we load the slot, we expect it to be 1 assertEq(uint(vm.load(address(test), bytes32(slot))), 1); } // If the target is a struct, you can specify the field depth: function testFindStruct() public { // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. uint256 slot_for_a_field = stdstore .target(address(test)) .sig(test.basicStruct.selector) .depth(0) .find(); uint256 slot_for_b_field = stdstore .target(address(test)) .sig(test.basicStruct.selector) .depth(1) .find(); assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1); assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2); } } // A complex storage contract contract Storage { struct UnpackedStruct { uint256 a; uint256 b; } constructor() { map_addr[msg.sender] = 1; } uint256 public exists = 1; mapping(address => uint256) public map_addr; // mapping(address => Packed) public map_packed; mapping(address => UnpackedStruct) public map_struct; mapping(address => mapping(address => uint256)) public deep_map; mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; UnpackedStruct public basicStruct = UnpackedStruct({ a: 1, b: 2 }); function hidden() public view returns (bytes32 t) { // an extremely hidden storage slot bytes32 slot = keccak256("my.random.var"); assembly { t := sload(slot) } } } ``` -------------------------------- ### Reward Calculation System: Timeline Gantt Chart Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md An example Gantt chart illustrating the reward calculation timeline, highlighting user activities like staking and reward claiming, alongside rate changes and commission updates. This visual aids in understanding the temporal aspects of reward accrual and distribution. ```mermaid gantt title Reward Calculation Timeline Example dateFormat YYYY-MM-DD axisFormat %m/%d section User Activity Stake 1000 PLUME :milestone, 2024-01-01, 0d Claim Rewards :milestone, 2024-01-30, 0d section Rate Changes Rate: 100/day (10% comm) :active, 2024-01-05, 10d Rate: 150/day (15% comm) :active, 2024-01-15, 10d Rate: 150/day (20% comm) :active, 2024-01-25, 5d ``` -------------------------------- ### Cancel Pending Spin in Raffle.sol Source: https://github.com/plumenetwork/contracts/blob/main/plume/SPIN.md A troubleshooting function to cancel a pending raffle spin or winner request. This is useful when a user's spin gets stuck in a pending state, preventing them from spinning again. This function requires the 'ADMIN_ROLE'. ```solidity function cancelPendingSpin(uint256 prizeId) public ``` -------------------------------- ### Initialize PlumeStaking System (Solidity) Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Initializes the PlumeStaking system and the AccessControlFacet after the Diamond proxy deployment. Requires owner address, minimum stake amount, cooldown period, maximum slashing vote duration, and maximum validator commission. ```solidity // After Diamond deployment, initialize PlumeStaking plumeStaking.initializePlume(initialOwner, minStake, cooldown, maxSlashVoteDuration, maxValidatorCommission) // Initialize AccessControlFacet accessControlFacet.initializeAccessControl() ``` -------------------------------- ### Sales Contract Initialization Source: https://github.com/plumenetwork/contracts/blob/main/arc/README.md Initializes the sales contract by setting the administrative address and the token factory address. ```APIDOC ## POST /initialize ### Description Initializes the sales contract, setting the admin and token factory addresses. ### Method POST ### Endpoint /initialize ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **admin** (address) - Required - The address of the contract administrator. - **factory** (address) - Required - The address of the ArcTokenFactory contract. ### Request Example ```json { "admin": "0x1234567890abcdef1234567890abcdef12345678", "factory": "0xabcdef1234567890abcdef1234567890abcdef12" } ``` ### Response #### Success Response (200) Indicates successful initialization. #### Response Example (No specific response body is defined for initialization success, typically a status code 200 or 204) #### Error Responses - **initializerFinished()**: If the initializer has already been called. - **AddressZeroCannotBeUsed()**: If zero addresses are provided for admin or factory. ``` -------------------------------- ### Plume Network Contract Build Instructions Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Commands to clean the project and build the Plume Network contracts using Forge. This process ensures a clean build environment and generates build information, utilizing the Intermediate Representation (IR). ```bash forge clean && forge build --via-ir --build-info ``` -------------------------------- ### Configuration Management Source: https://github.com/plumenetwork/contracts/blob/main/arc/README.md APIs for configuring core settings of the sales contract, including purchase tokens and storefront metadata. ```APIDOC ## PUT /setPurchaseToken ### Description Sets the ERC20 token address that will be used for purchasing ArcTokens (e.g., USDC, DAI). ### Method PUT ### Endpoint /setPurchaseToken ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **purchaseTokenAddress** (address) - Required - The address of the ERC20 token contract to be used for purchases. ### Request Example ```json { "purchaseTokenAddress": "0xabcdef1234567890abcdef1234567890abcdef12" } ``` ### Response #### Success Response (200) Indicates the purchase token address has been successfully updated. #### Response Example (No specific response body is defined for success) #### Error Responses - **DEFAULT_ADMIN_ROLE**: Only users with the default admin role can call this function. - **InvalidPurchaseTokenAddress()**: If the provided address is invalid or zero. - **CannotChangePurchaseTokenWithActiveSales()**: If there are active token sales, the purchase token cannot be changed. ``` ```APIDOC ## PUT /setTokenFactory ### Description Sets the `ArcTokenFactory` address, which is used by the sales contract to verify that newly enabled tokens were indeed created by the official factory. ### Method PUT ### Endpoint /setTokenFactory ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **factoryAddress** (address) - Required - The address of the `ArcTokenFactory` contract. ### Request Example ```json { "factoryAddress": "0x1234567890abcdef1234567890abcdef12345678" } ``` ### Response #### Success Response (200) Indicates the token factory address has been successfully updated. #### Response Example (No specific response body is defined for success) #### Error Responses - **DEFAULT_ADMIN_ROLE**: Only users with the default admin role can call this function. - **AddressZeroCannotBeUsed()**: If the provided `factoryAddress` is the zero address. ``` ```APIDOC ## POST /setStorefrontConfig ### Description Configures metadata for an off-chain storefront associated with a specific token sale. This includes details like domain names. ### Method POST ### Endpoint /setStorefrontConfig ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **_tokenContract** (address) - Required - The contract address of the ArcToken for which to configure the storefront. - **_domain** (string) - Required - The domain name for the storefront (e.g., "mycooltoken.com"). - **...** (additional fields may exist for other metadata) ### Request Example ```json { "_tokenContract": "0x1111111111111111111111111111111111111111", "_domain": "mytokenstore.xyz" } ``` ### Response #### Success Response (200) Indicates the storefront configuration has been successfully set. #### Response Example (No specific response body is defined for success) #### Error Responses - **onlyTokenAdmin**: Only token admins can set storefront configurations. - **DomainCannotBeEmpty()**: If the provided `_domain` is empty. - **DomainAlreadyInUse(string domain)**: If the `_domain` is already associated with another token. ``` -------------------------------- ### Solidity: Test Contract with Hoax and Prank Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/README.md Demonstrates the usage of `hoax` and `startHoax` functions within a Solidity test contract. These functions are used to simulate specific `msg.sender` and `msg.value` conditions for testing. ```solidity // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "forge-std/Test.sol"; // Inherit the stdCheats contract StdCheatsTest is Test { Bar test; function setUp() public { test = new Bar(); } function testHoax() public { // we call `hoax`, which gives the target address // eth and then calls `prank` hoax(address(1337)); test.bar{value: 100}(address(1337)); // overloaded to allow you to specify how much eth to // initialize the address with hoax(address(1337), 1); test.bar{value: 1}(address(1337)); } function testStartHoax() public { // we call `startHoax`, which gives the target address // eth and then calls `startPrank` // // it is also overloaded so that you can specify an eth amount startHoax(address(1337)); test.bar{value: 100}(address(1337)); test.bar{value: 100}(address(1337)); vm.stopPrank(); test.bar(address(this)); } } contract Bar { function bar(address expectedSender) public payable { require(msg.sender == expectedSender, "!prank"); } } ``` -------------------------------- ### Solidity: Console Logging with console.sol (Hardhat Compatible) Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/README.md Demonstrates the usage of `console.log` for debugging in Solidity, emphasizing compatibility with Hardhat. Note that `uint256` and `int256` types may not be properly decoded in Forge traces due to a known bug in `console.sol`. ```solidity // import it indirectly via Test.sol import "forge-std/Test.sol"; // or directly import it import "forge-std/console.sol"; ... console.log(someValue); ``` -------------------------------- ### Deploy Plume Spin and Raffle Contracts Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Deployment script for Spin and Raffle contracts on the Plume Network, including Supra whitelisting. This command sources environment variables and executes the deployment script using Forge, broadcasting the transaction to the network. ```bash source .env && forge script script/DeploySpinRaffleContracts.s.sol \ --rpc-url https://rpc.plume.org \ --broadcast \ --via-ir ``` -------------------------------- ### AccessControlFacet Initialization Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Solidity code for initializing the AccessControlFacet. This function must be called after the facet is deployed to set up roles and permissions, granting DEFAULT_ADMIN_ROLE and ADMIN_ROLE to the caller. ```Solidity // Must be called after facet deployment accessControlFacet.initializeAccessControl() ``` -------------------------------- ### Deploy and Manage Asset Vaults in Smart Wallets (Solidity) Source: https://context7.com/plumenetwork/contracts/llms.txt This code demonstrates the creation and management of asset vaults associated with smart wallets. It shows how to compute a smart wallet's address, deploy its asset vault, retrieve the vault's address, and handle asset deposits and redemptions. It also covers approving tokens for vault usage and fulfilling deposit requests. Dependencies include ISmartWallet, IAssetVault, IERC20, and IAssetToken. ```solidity // Smart wallet automatically exists for every EOA via proxy address smartWallet = walletFactory.computeWalletAddress(msg.sender); // Deploy asset vault for user ISmartWallet(smartWallet).deployAssetVault(); // Get vault address IAssetVault vault = ISmartWallet(smartWallet).getAssetVault(); console.log("Asset vault deployed at:", address(vault)); // Create deposit request to vault uint256 depositAmount = 1000e6; // 1000 USDC IERC20(usdcAddress).approve(address(vault), depositAmount); IAssetVault(address(vault)).requestDeposit( assetTokenAddress, usdcAddress, // currency token depositAmount, msg.sender ); // Asset token admin processes the deposit uint256 depositId = 0; IAssetToken(assetTokenAddress).fulfillDeposit( msg.sender, depositId ); // Check vault balances uint256 lockedAssets = ISmartWallet(smartWallet).getLockedAssetTokenBalance( assetTokenAddress ); console.log("Locked in vault:", lockedAssets); // Request redemption IAssetVault(address(vault)).requestRedeem( assetTokenAddress, 100e18, // 100 asset tokens msg.sender ); ``` -------------------------------- ### Solidity: Console Logging with console2.sol Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/README.md Shows how to use `console2.log` for debugging in Solidity tests. This method is recommended for use with Forge as it provides decoded logs in traces. It can be imported directly or indirectly via `Test.sol`. ```solidity // import it indirectly via Test.sol import "forge-std/Test.sol"; // or directly import it import "forge-std/console2.sol"; ... console2.log(someValue); ``` -------------------------------- ### Spin Contract Functions Source: https://github.com/plumenetwork/contracts/blob/main/plume/SPIN.md This section covers the key functions of the Spin contract, including initiating spins, handling oracle callbacks, managing user data, and administrative functions. ```APIDOC ## Spin Contract API ### `startSpin()` **Description**: User-callable function to initiate a spin. **Method**: `POST` (or relevant transaction method) **Endpoint**: `/spin/startSpin` (Conceptual endpoint for transaction) **Parameters**: #### Query Parameters - **`spinPrice`** (uint256) - Required - The price to initiate a spin. #### Request Body (Not applicable for this function, typically called with parameters) ### `handleRandomness(...)` **Description**: Callback function for the Supra oracle. Processes the spin result and updates user state. **Method**: Internal/Oracle Callback **Endpoint**: N/A (Internal callback) **Parameters**: (Details depend on oracle integration) ### `spendRaffleTickets(...)` **Description**: Allows the `Raffle` contract to deduct tickets from a user's balance. **Method**: Internal/Contract-to-Contract Call **Endpoint**: N/A (Internal call from Raffle contract) **Parameters**: (Details depend on Raffle contract interaction) ### `pause()` / `unpause()` **Description**: Pauses or unpauses the `startSpin` functionality. **Method**: `POST` (or relevant transaction method) **Endpoint**: `/spin/pause`, `/spin/unpause` (Conceptual endpoints) **Parameters**: (None required) ### `adminWithdraw(...)` **Description**: Allows admin to withdraw PLUME tokens from the contract balance. **Method**: `POST` (or relevant transaction method) **Endpoint**: `/spin/adminWithdraw` (Conceptual endpoint) **Parameters**: (Details depend on withdrawal mechanism) ### `cancelPendingSpin(address user)` **Description**: Escape hatch to cancel a user's spin request stuck pending an oracle callback. **Method**: `POST` (or relevant transaction method) **Endpoint**: `/spin/cancelPendingSpin` (Conceptual endpoint) **Parameters**: #### Query Parameters - **`user`** (address) - Required - The address of the user whose spin request to cancel. ### `set...()` functions **Description**: A suite of functions for configuring contract parameters (e.g., `setSpinPrice`, `setRaffleContract`). **Method**: `POST` (or relevant transaction method) **Endpoint**: `/spin/setSpinPrice`, `/spin/setRaffleContract`, etc. (Conceptual endpoints) **Parameters**: (Vary depending on the specific set function) ### `currentStreak(address user)` **Description**: View function to get a user's current consecutive daily spin streak. **Method**: `GET` (or relevant view call) **Endpoint**: `/spin/currentStreak` (Conceptual endpoint) **Parameters**: #### Query Parameters - **`user`** (address) - Required - The address of the user. ### `getUserData(address user)` **Description**: View function that returns a comprehensive struct of a user's spin-related data. **Method**: `GET` (or relevant view call) **Endpoint**: `/spin/getUserData` (Conceptual endpoint) **Parameters**: #### Query Parameters - **`user`** (address) - Required - The address of the user. ### `getWeeklyJackpot()` **Description**: View function to get the current week's jackpot prize and required streak. **Method**: `GET` (or relevant view call) **Endpoint**: `/spin/getWeeklyJackpot` (Conceptual endpoint) **Parameters**: (None required) ### Events - `SpinRequested(uint256 indexed nonce, address indexed user)` - `SpinCompleted(address indexed walletAddress, string rewardCategory, uint256 rewardAmount)` - `RaffleTicketsSpent(address indexed walletAddress, uint256 ticketsUsed, uint256 remainingTickets)` - `NotEnoughStreak(string message)` - `JackpotAlreadyClaimed(string message)` ### Errors - `AlreadySpunToday()` - `CampaignNotStarted()` - `InvalidNonce()` - `SpinRequestPending(address user)` ``` -------------------------------- ### Winner Selection Initiation in Raffle.sol Source: https://github.com/plumenetwork/contracts/blob/main/plume/SPIN.md Initiates the process for selecting a winner for a specified prize. This function requires the 'ADMIN_ROLE' to be called. It is designed to work with external oracles for secure random selection. ```solidity function requestWinner(uint256 prizeId) public ``` -------------------------------- ### Generate Cheatcodes with vm.py Script Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/CONTRIBUTING.md This script generates cheatcodes for the Vm.sol file from a JSON configuration. It can automatically use the default cheatcodes.json or accept a custom JSON file path via the --from flag. Ensure this script is run when modifying native cheatcodes or adding new ones. ```shell ./scripts/vm.py --from path/to/cheatcodes.json ``` -------------------------------- ### Token Information Retrieval Source: https://github.com/plumenetwork/contracts/blob/main/arc/README.md APIs for retrieving detailed information about enabled token sales and their configurations. ```APIDOC ## GET /getTokenInfo ### Description Retrieves the sales status and details for a specific ArcToken, including whether it's enabled, its price, total supply for sale, and tokens already sold. ### Method GET ### Endpoint /getTokenInfo ### Parameters #### Path Parameters None #### Query Parameters - **_tokenContract** (address) - Required - The contract address of the ArcToken to query. ### Request Example `GET /getTokenInfo?_tokenContract=0x1111111111111111111111111111111111111111` ### Response #### Success Response (200) Returns the sales status and details for the specified token. - **isEnabled** (bool) - Whether the token sale is currently enabled. - **price** (uint256) - The price per full ArcToken unit in the purchase token. - **totalForSale** (uint256) - The total number of tokens made available for sale. - **sold** (uint256) - The number of tokens already sold. #### Response Example ```json { "isEnabled": true, "price": 500000000000000000, "totalForSale": 1000000000000000000, "sold": 500000000000000000 } ``` ``` ```APIDOC ## GET /isEnabled ### Description Checks if a specific ArcToken sale is currently enabled. ### Method GET ### Endpoint /isEnabled ### Parameters #### Path Parameters None #### Query Parameters - **_tokenContract** (address) - Required - The contract address of the ArcToken to check. ### Request Example `GET /isEnabled?_tokenContract=0x1111111111111111111111111111111111111111` ### Response #### Success Response (200) Returns a boolean indicating if the token sale is enabled. - **enabled** (bool) - `true` if the token sale is enabled, `false` otherwise. #### Response Example ```json { "enabled": true } ``` ``` ```APIDOC ## GET /getMaxNumberOfTokens ### Description Returns the remaining number of tokens available for sale for a given ArcToken, expressed in base units. ### Method GET ### Endpoint /getMaxNumberOfTokens ### Parameters #### Path Parameters None #### Query Parameters - **_tokenContract** (address) - Required - The contract address of the ArcToken to query. ### Request Example `GET /getMaxNumberOfTokens?_tokenContract=0x1111111111111111111111111111111111111111` ### Response #### Success Response (200) Returns the number of tokens still available for sale. - **remainingTokens** (uint256) - The quantity of tokens remaining for sale. #### Response Example ```json { "remainingTokens": 500000000000000000 } ``` ``` ```APIDOC ## GET /getTokenPrice ### Description Returns the price per full `ArcToken` unit, denominated in the currently configured purchase token. ### Method GET ### Endpoint /getTokenPrice ### Parameters #### Path Parameters None #### Query Parameters - **_tokenContract** (address) - Required - The contract address of the ArcToken whose price is being queried. ### Request Example `GET /getTokenPrice?_tokenContract=0x1111111111111111111111111111111111111111` ### Response #### Success Response (200) Returns the price of one unit of the ArcToken. - **price** (uint256) - The price in the purchase token's smallest unit. #### Response Example ```json { "price": 500000000000000000 } ``` ``` ```APIDOC ## GET /getStorefrontConfig ### Description Retrieves the storefront configuration details associated with a specific ArcToken contract. ### Method GET ### Endpoint /getStorefrontConfig ### Parameters #### Path Parameters None #### Query Parameters - **_tokenContract** (address) - Required - The contract address of the ArcToken whose storefront configuration is requested. ### Request Example `GET /getStorefrontConfig?_tokenContract=0x1111111111111111111111111111111111111111` ### Response #### Success Response (200) Returns the storefront configuration, including the associated domain. - **domain** (string) - The domain name configured for the storefront. - **...** (other configuration fields may be returned) #### Response Example ```json { "domain": "mytokenstore.xyz" } ``` #### Error Responses - **NoConfigForDomain(string domain)**: If no storefront configuration exists for the specified token. ``` ```APIDOC ## GET /getStorefrontConfigByDomain ### Description Retrieves the storefront configuration details associated with a given domain name. ### Method GET ### Endpoint /getStorefrontConfigByDomain ### Parameters #### Path Parameters None #### Query Parameters - **_domain** (string) - Required - The domain name to look up. ### Request Example `GET /getStorefrontConfigByDomain?_domain=mytokenstore.xyz` ### Response #### Success Response (200) Returns the storefront configuration associated with the domain. - **tokenContract** (address) - The ArcToken contract address linked to this domain. - **...** (other configuration fields may be returned) #### Response Example ```json { "tokenContract": "0x1111111111111111111111111111111111111111" } ``` #### Error Responses - **NoConfigForDomain(string domain)**: If no storefront configuration exists for the specified domain. ``` ```APIDOC ## GET /getAddressByDomain ### Description Returns the `ArcToken` contract address that is associated with a given domain name. ### Method GET ### Endpoint /getAddressByDomain ### Parameters #### Path Parameters None #### Query Parameters - **_domain** (string) - Required - The domain name to look up. ### Request Example `GET /getAddressByDomain?_domain=mytokenstore.xyz` ### Response #### Success Response (200) Returns the ArcToken contract address linked to the domain. - **tokenContractAddress** (address) - The address of the ArcToken contract. #### Response Example ```json { "tokenContractAddress": "0x1111111111111111111111111111111111111111" } ``` #### Error Responses - **NoConfigForDomain(string domain)**: If no mapping exists for the provided domain. ``` ```APIDOC ## GET /purchaseToken ### Description Returns the address of the ERC20 token currently configured for use in purchasing ArcTokens. ### Method GET ### Endpoint /purchaseToken ### Parameters #### Path Parameters None #### Query Parameters None ### Request Example `GET /purchaseToken` ### Response #### Success Response (200) Returns the address of the purchase token. - **purchaseTokenAddress** (address) - The address of the active purchase token. #### Response Example ```json { "purchaseTokenAddress": "0xabcdef1234567890abcdef1234567890abcdef12" } ``` #### Error Responses - **PurchaseTokenNotSet()**: If no purchase token has been set yet. ``` ```APIDOC ## GET /tokenFactory ### Description Returns the address of the `ArcTokenFactory` contract that is currently configured for the sales contract. ### Method GET ### Endpoint /tokenFactory ### Parameters #### Path Parameters None #### Query Parameters None ### Request Example `GET /tokenFactory` ### Response #### Success Response (200) Returns the address of the token factory. - **tokenFactoryAddress** (address) - The address of the configured ArcTokenFactory. #### Response Example ```json { "tokenFactoryAddress": "0x1234567890abcdef1234567890abcdef12345678" } ``` #### Error Responses - **TokenFactoryNotSet()**: If no token factory has been configured. ``` -------------------------------- ### Build with Specific Solidity Compiler Versions Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/CONTRIBUTING.md Compiles the Foundry project using different specified Solidity compiler versions, while skipping tests. This verifies compatibility across various compiler targets. ```shell forge build --skip test --use solc:0.6.2 forge build --skip test --use solc:0.6.12 forge build --skip test --use solc:0.7.0 forge build --skip test --use solc:0.7.6 forge build --skip test --use solc:0.8.0 ``` -------------------------------- ### Plume Network Environment Configuration Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Environment variables for configuring network settings, contract addresses, and Oracle details for Plume Network. This includes RPC URLs, private keys, proxy addresses for upgrades, and addresses for Supra Oracle services. ```dotenv # Network RPC_URL="https://rpc.plume.org" PRIVATE_KEY= # Contract Addresses (for upgrades) SPIN_PROXY_ADDRESS= RAFFLE_PROXY_ADDRESS= # Supra Oracle SUPRA_ROUTER_ADDRESS=0xE1062AC81e76ebd17b1e283CEed7B9E8B2F749A5 SUPRA_DEPOSIT_CONTRACT_ADDRESS=0x6DA36159Fe94877fF7cF226DBB164ef7f8919b9b SUPRA_GENERATOR_CONTRACT_ADDRESS=0x8cC8bbE991d8B4371551B4e666Aa212f9D5f165e # Utilities DATETIME_ADDRESS=0x06a40Ec10d03998634d89d2e098F079D06A8FA83 BLOCKSCOUT_URL=https://explorer.plume.org/api? ``` -------------------------------- ### Run Tests with Forge Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/CONTRIBUTING.md Executes all tests within the Foundry project with verbose output. This is a crucial step to ensure code changes do not break existing functionality. ```shell forge test -vvv ``` -------------------------------- ### ManagementFacet System Parameter Configuration Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Functions to configure system-wide parameters and perform administrative tasks. This includes setting minimum stake, cooldown durations, slashing parameters, and managing validator records. ```Solidity function setMinStakeAmount(uint256) function setCooldownInterval(uint256) function adminWithdraw(address, uint256, address) function setMaxSlashVoteDuration(uint256) function setMaxAllowedValidatorCommission(uint256) function adminClearValidatorRecord(address, uint16) function adminBatchClearValidatorRecords(address[], uint16) function setMaxCommissionCheckpoints(uint16) function setMaxValidatorPercentage(uint256) function pruneCommissionCheckpoints(uint16, uint256) function pruneRewardRateCheckpoints(uint16, address, uint256) function addHistoricalRewardToken(address) function removeHistoricalRewardToken(address) ``` -------------------------------- ### Check Code Formatting with Forge Source: https://github.com/plumenetwork/contracts/blob/main/arc/lib/forge-std/CONTRIBUTING.md Ensures that the code adheres to Foundry's formatting standards. This command checks if the code is formatted correctly without making changes. ```shell forge fmt --check ``` -------------------------------- ### Configure Reward Tokens and Rates in PlumeStaking (Solidity) Source: https://context7.com/plumenetwork/contracts/llms.txt This snippet demonstrates how to manage reward tokens and their rates within the PlumeStaking contract. It covers adding new reward tokens, setting initial and maximum rates, updating rates for multiple tokens, removing tokens, setting the treasury address, and querying current reward information. Dependencies include the IRewardsFacet and IPlumeStaking interfaces. ```solidity // Add new reward token (creates checkpoints for all validators) IRewardsFacet(stakingDiamond).addRewardToken( usdcAddress, 1e15, // initial rate: 1e15 tokens per second per staked token 5e15 // max rate: 5e15 ); // Set reward rates for multiple tokens address[] memory tokens = [plumeAddress, usdcAddress]; uint256[] memory rates = [ 2e15, // 2e15 PLUME per second per staked token 1.5e15 // 1.5e15 USDC per second per staked token ]; IRewardsFacet(stakingDiamond).setRewardRates(tokens, rates); // Update max rate for a token IRewardsFacet(stakingDiamond).setMaxRewardRate(usdcAddress, 10e15); // Remove a reward token (creates final zero-rate checkpoint) IRewardsFacet(stakingDiamond).removeRewardToken(oldTokenAddress); // Set treasury address for reward distributions IRewardsFacet(stakingDiamond).setTreasury(treasuryAddress); // Get current reward configuration IPlumeStaking.RewardInfo memory rewardInfo = IRewardsFacet(stakingDiamond).tokenRewardInfo(usdcAddress); console.log("Current rate:", rewardInfo.rate); console.log("Max rate:", rewardInfo.maxRate); ``` -------------------------------- ### Commission System Flow (Sequence Diagram) Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Visualizes the commission system's flow, from user staking and reward accrual to commission deduction, validator claims, and treasury distribution. It highlights the 7-day timelock for commission claims. ```Mermaid sequenceDiagram participant User participant StakingContract participant Validator participant Treasury User->>StakingContract: stake(validatorId) Note over StakingContract: Rewards accrue over time User->>StakingContract: claim() StakingContract->>StakingContract: Calculate gross rewards StakingContract->>StakingContract: Deduct commission StakingContract->>StakingContract: Update validator accrued commission StakingContract->>Treasury: distributeReward(user, netAmount) Treasury->>User: Transfer net rewards Validator->>StakingContract: requestCommissionClaim() Note over StakingContract: 7-day timelock Validator->>StakingContract: finalizeCommissionClaim() StakingContract->>Treasury: distributeReward(validator, commission) Treasury->>Validator: Transfer commission ``` -------------------------------- ### Solidity: Create and Configure Arc Token with Sales Source: https://context7.com/plumenetwork/contracts/llms.txt Deploys and configures an Arc token, including setting up restriction modules, a purchase contract, and enabling token sales. This process involves deploying a RestrictionsRouter, ArcTokenFactory, and the Arc token itself, followed by configuring whitelist restrictions and enabling a token sale through a purchase contract. Dependencies include OpenZeppelin's ERC1967Proxy and various Arc token interfaces. ```solidity // 1. Deploy RestrictionsRouter (one-time setup) RestrictionsRouter router = new RestrictionsRouter(); ERC1967Proxy routerProxy = new ERC1967Proxy( address(router), abi.encodeWithSelector(RestrictionsRouter.initialize.selector, adminAddress) ); // 2. Deploy ArcTokenFactory ArcTokenFactory factory = new ArcTokenFactory(); ERC1967Proxy factoryProxy = new ERC1967Proxy( address(factory), abi.encodeWithSelector(ArcTokenFactory.initialize.selector, address(routerProxy)) ); // 3. Create new Arc token (deploys unique implementation + proxy + restriction modules) address tokenProxy = IArcTokenFactory(address(factoryProxy)).createToken( "Real Estate Fund I", // name "aRE1", // symbol 1000000e18, // initial supply (1M tokens) usdcAddress, // yield token (USDC) treasuryAddress, // initial holder 18, // decimals "ipfs://Qm.../metadata.json" // tokenURI ); // 4. Configure whitelist restrictions for the token address whitelistModule = ArcToken(tokenProxy).getRestrictionModule( keccak256("TRANSFER_RESTRICTION_TYPE") ); WhitelistRestrictions(whitelistModule).setTransfersAllowed(true); WhitelistRestrictions(whitelistModule).batchAddToWhitelist([ buyerAddress1, buyerAddress2, purchaseContractAddress ]); // 5. Deploy and configure purchase contract ArcTokenPurchase purchase = new ArcTokenPurchase(); ERC1967Proxy purchaseProxy = new ERC1967Proxy( address(purchase), abi.encodeWithSelector( ArcTokenPurchase.initialize.selector, adminAddress, address(factoryProxy) ) ); IArcTokenPurchase(address(purchaseProxy)).setPurchaseToken(usdcAddress); // 6. Enable token sale IERC20(tokenProxy).transfer(address(purchaseProxy), 500000e18); // Transfer 500k tokens for sale IArcTokenPurchase(address(purchaseProxy)).enableToken( tokenProxy, 500000e18, // 500k tokens for sale 10e6 // price: 10 USDC (6 decimals) per token ); ``` -------------------------------- ### Arc Token: Upgrade Token Implementations (Solidity) Source: https://context7.com/plumenetwork/contracts/llms.txt Explains the process of upgrading Arc Token implementations to a new version. This involves deploying a new implementation contract, whitelisting it in the factory, and then initiating the upgrade for a specific token proxy, ensuring state persistence. ```solidity // Deploy new ArcToken implementation ArcToken newImplementation = new ArcToken(); // Whitelist the new implementation in factory bytes32 codeHash; assembly { codeHash := extcodehash(newImplementation) } IArcTokenFactory(address(factoryProxy)).whitelistImplementation(address(newImplementation)); // Upgrade a specific token to the new implementation IArcTokenFactory(address(factoryProxy)).upgradeToken( tokenProxy, address(newImplementation) ); // Verify upgrade address currentImpl = IArcTokenFactory(address(factoryProxy)).getTokenImplementation(tokenProxy); require(currentImpl == address(newImplementation), "Upgrade failed"); // Token continues operating with same state, new logic uint256 balance = IERC20(tokenProxy).balanceOf(msg.sender); console.log("Balance after upgrade:", balance); ``` -------------------------------- ### ManagementFacet View Functions Source: https://github.com/plumenetwork/contracts/blob/main/plume/README.md Functions to retrieve current system parameter settings. These include the minimum stake amount and the unstaking cooldown duration. ```Solidity function getMinStakeAmount() returns uint256 function getCooldownInterval() returns uint256 ``` -------------------------------- ### Execute Operations with Signatures for Gasless Transactions in Solidity Source: https://context7.com/plumenetwork/contracts/llms.txt This snippet outlines the process of creating signed operations off-chain using a user's private key and then executing these operations on-chain via a relayer using a smart wallet. It covers single operations, batch operations, and nonce checking. ```solidity // User creates signed operation off-chain bytes32 operationHash = keccak256(abi.encodePacked( smartWallet, targetContract, value, data, nonce, deadline )); bytes32 ethSignedHash = keccak256(abi.encodePacked( "\x19Ethereum Signed Message:\n32", operationHash )); (uint8 v, bytes32 r, bytes32 s) = vm.sign(userPrivateKey, ethSignedHash); bytes memory signature = abi.encodePacked(r, s, v); // Relayer executes operation with user's signature ISmartWallet(smartWallet).executeWithSignature( targetContract, value, data, nonce, deadline, signature ); // Batch operations address[] memory targets = [contract1, contract2]; uint256[] memory values = [0, 0]; bytes[] memory datas = [data1, data2]; ISmartWallet(smartWallet).executeBatchWithSignature( targets, values, datas, nonce, deadline, signature ); // Check nonce before signing uint256 currentNonce = ISmartWallet(smartWallet).getNonce(msg.sender); ```