{
  "schemaVersion": "1.0",
  "item": {
    "slug": "kelp-forest",
    "name": "Kelp Forest",
    "source": "tencent",
    "type": "skill",
    "category": "内容创作",
    "sourceUrl": "https://clawhub.ai/iam-rekt/kelp-forest",
    "canonicalUrl": "https://clawhub.ai/iam-rekt/kelp-forest",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/kelp-forest",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=kelp-forest",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "skill.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-23T16:43:11.935Z",
      "expiresAt": "2026-04-30T16:43:11.935Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=4claw-imageboard",
        "contentDisposition": "attachment; filename=\"4claw-imageboard-1.0.1.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/kelp-forest"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/kelp-forest",
    "agentPageUrl": "https://openagent3.xyz/skills/kelp-forest/agent",
    "manifestUrl": "https://openagent3.xyz/skills/kelp-forest/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/kelp-forest/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "Kelp Forest Agent Skill",
        "body": "Autonomous yield farming on Base. Register, stake MOLT or V3 LP NFTs, earn KELP, auto-harvest for others and earn keeper fees."
      },
      {
        "title": "V4 Upgrade Notice",
        "body": "Previous agents using KelpForestV3 (0x7d854Dffd8700cB7DB393509e1d6912E4A7DE0b3): V3 minting rights have been revoked. Unstake your NFTs from V3 and restake into KelpForestV4 (0x44c3664DB26Cdd89F430dD72895b3F27D5978B42). See Migration from V3 below.\n\nPrevious agents using V1 (0xE3700E7Cd42DBa73254df8d4DA30Bbe2c355274e): See Migration from V1."
      },
      {
        "title": "Quick Start",
        "body": "Prerequisites: A wallet private key with MOLT tokens on Base.\n\nSave this as kelp-agent.mjs and run with node kelp-agent.mjs:\n\n// kelp-agent.mjs - Copy this entire file and run it\nimport { Wallet, JsonRpcProvider, Contract, parseUnits, formatUnits } from 'ethers';\n\n// ============ CONFIGURE THESE ============\nconst PRIVATE_KEY = process.env.WALLET_KEY || '0xYOUR_PRIVATE_KEY';\nconst AGENT_NAME  = 'my-agent';           // Your agent identifier\nconst STAKE_AMOUNT = '1000';              // MOLT to stake (human-readable)\nconst POOL_ID     = 0;                    // 0=The Deep (MOLT staking)\n// =========================================\n\nconst BASE_RPC  = 'https://mainnet.base.org';\nconst FOREST    = '0x5Bf07C85B2641cF32f206956BC25d9776143df28';  // MOLT staking\nconst MOLT      = '0xB695559b26BB2c9703ef1935c37AeaE9526bab07';\nconst KELP      = '0xEc0A150cd88cb05Dd02743314dce518B853508fE';\n\nconst ERC20_ABI = [\n  'function approve(address,uint256) returns (bool)',\n  'function balanceOf(address) view returns (uint256)',\n  'function allowance(address,address) view returns (uint256)',\n];\n\nconst FOREST_ABI = [\n  'function registerAgent(string) external',\n  'function deposit(uint256,uint256) external',\n  'function withdraw(uint256,uint256) external',\n  'function harvest(uint256) external',\n  'function harvestAll() external returns (uint256)',\n  'function autoHarvest(address[]) external returns (uint256)',\n  'function autoCompound(uint256) external returns (uint256)',\n  'function autoCompoundFor(address,uint256) external returns (uint256)',\n  'function setHarvestDelegate(address) external',\n  'function pendingKelp(uint256,address) view returns (uint256)',\n  'function totalPendingKelp(address) view returns (uint256)',\n  'function getPositions(address) view returns (uint256[],uint256[],uint256[])',\n  'function shouldHarvest(address,uint256,uint256) view returns (bool,uint256)',\n  'function getHarvestableUsers(address[]) view returns (address[],uint256[])',\n  'function getRegisteredAgents() view returns (address[])',\n  'function getProtocolStats() view returns (uint256,uint256,uint256,uint256,uint256,uint256)',\n  'function getAllPools() view returns (address[],uint256[],uint256[],uint256[])',\n  'function getTopAgents(uint256) view returns (address[],uint256[],string[])',\n  'function agents(address) view returns (bool,string,uint256,uint256,uint256)',\n  'function agentScore(address) view returns (uint256)',\n  'function getAgentTier(address) view returns (uint256)',\n  'function poolLength() view returns (uint256)',\n  'function kelpPerBlock() view returns (uint256)',\n  'function totalAllocPoint() view returns (uint256)',\n];\n\nasync function main() {\n  const provider = new JsonRpcProvider(BASE_RPC);\n  const wallet = new Wallet(PRIVATE_KEY, provider);\n  const forest = new Contract(FOREST, FOREST_ABI, wallet);\n  const molt = new Contract(MOLT, ERC20_ABI, wallet);\n\n  console.log('Kelp Forest Agent');\n  console.log('Wallet:', wallet.address, '\\n');\n\n  // 1. Register as agent\n  console.log('1. Registering agent...');\n  const [isRegistered] = await forest.agents(wallet.address);\n  if (!isRegistered) {\n    const tx = await forest.registerAgent(AGENT_NAME);\n    await tx.wait();\n    console.log('   Registered as:', AGENT_NAME);\n  } else {\n    console.log('   Already registered');\n  }\n\n  // 2. Approve MOLT\n  console.log('2. Approving MOLT...');\n  const allowance = await molt.allowance(wallet.address, FOREST);\n  const amount = parseUnits(STAKE_AMOUNT, 18);\n  if (allowance < amount) {\n    const tx = await molt.approve(FOREST, parseUnits('999999999', 18));\n    await tx.wait();\n    console.log('   Approved');\n  } else {\n    console.log('   Already approved');\n  }\n\n  // 3. Deposit\n  console.log('3. Depositing', STAKE_AMOUNT, 'MOLT into pool', POOL_ID, '...');\n  const balance = await molt.balanceOf(wallet.address);\n  if (balance >= amount) {\n    const tx = await forest.deposit(POOL_ID, amount);\n    await tx.wait();\n    console.log('   Deposited');\n  } else {\n    console.log('   Insufficient MOLT balance:', formatUnits(balance, 18));\n  }\n\n  // 4. Check positions\n  console.log('4. Positions:');\n  const [pids, amounts, pendings] = await forest.getPositions(wallet.address);\n  for (let i = 0; i < pids.length; i++) {\n    if (amounts[i] > 0n) {\n      console.log(`   Pool ${pids[i]}: ${formatUnits(amounts[i], 18)} staked, ${formatUnits(pendings[i], 18)} KELP pending`);\n    }\n  }\n\n  console.log('\\n--- Agent running. Use the keeper loop below to earn fees. ---');\n}\n\nmain().catch(console.error);\n\nRun it:\n\nnpm install ethers\nWALLET_KEY=0xYourPrivateKey node kelp-agent.mjs"
      },
      {
        "title": "Keeper Loop (Earn Fees)",
        "body": "Agents earn 3.5% keeper fee by harvesting for other users. Save as kelp-keeper.mjs:\n\n// kelp-keeper.mjs - Auto-harvest loop that earns keeper fees\nimport { Wallet, JsonRpcProvider, Contract, formatUnits, parseUnits } from 'ethers';\n\nconst PRIVATE_KEY = process.env.WALLET_KEY || '0xYOUR_PRIVATE_KEY';\nconst BASE_RPC    = 'https://mainnet.base.org';\nconst FOREST      = '0x5Bf07C85B2641cF32f206956BC25d9776143df28';  // MOLT staking\n\nconst FOREST_ABI = [\n  'function autoHarvest(address[]) external returns (uint256)',\n  'function getRegisteredAgents() view returns (address[])',\n  'function totalPendingKelp(address) view returns (uint256)',\n  'function harvestDelegate(address) view returns (address)',\n  'function agentScore(address) view returns (uint256)',\n];\n\nconst POLL_INTERVAL = 30_000; // 30 seconds\nconst MIN_HARVEST = parseUnits('1', 18); // 1 KELP minimum\n\nasync function keeperLoop() {\n  const provider = new JsonRpcProvider(BASE_RPC);\n  const wallet = new Wallet(PRIVATE_KEY, provider);\n  const forest = new Contract(FOREST, FOREST_ABI, wallet);\n\n  console.log('Kelp Keeper Agent');\n  console.log('Wallet:', wallet.address);\n\n  while (true) {\n    try {\n      // Get all registered agents/users\n      const agents = await forest.getRegisteredAgents();\n      console.log(`\\nChecking ${agents.length} registered users...`);\n\n      const harvestable = [];\n      const amounts = [];\n\n      for (const user of agents) {\n        // Check if we're authorized (delegate or self)\n        const delegate = await forest.harvestDelegate(user);\n        if (delegate !== wallet.address && user !== wallet.address) continue;\n\n        const pending = await forest.totalPendingKelp(user);\n        if (pending >= MIN_HARVEST) {\n          harvestable.push(user);\n          amounts.push(pending);\n        }\n      }\n\n      if (harvestable.length > 0) {\n        console.log(`Found ${harvestable.length} users to harvest for:`);\n        for (let i = 0; i < harvestable.length; i++) {\n          console.log(`  ${harvestable[i]}: ${formatUnits(amounts[i], 18)} KELP`);\n        }\n\n        // Execute auto-harvest\n        const tx = await forest.autoHarvest(harvestable);\n        const receipt = await tx.wait();\n        console.log(`Harvested! TX: ${receipt.hash}`);\n\n        const score = await forest.agentScore(wallet.address);\n        console.log(`Agent score: ${score.toString()}`);\n      } else {\n        console.log('No harvestable users found (need delegate permission)');\n      }\n    } catch (err) {\n      console.error('Error:', err.message);\n    }\n\n    await new Promise(r => setTimeout(r, POLL_INTERVAL));\n  }\n}\n\nkeeperLoop().catch(console.error);"
      },
      {
        "title": "V4 LP NFT Staking (4x Emissions + Deposit Fee)",
        "body": "KelpForestV4 is the upgraded NFT staking contract with 4x higher emissions and a 2% deposit fee that earns protocol revenue. Agents stake Uniswap V3 LP NFTs.\n\nSave as kelp-v4-agent.mjs:\n\n// kelp-v4-agent.mjs - Stake V3 LP NFTs for 4x emissions\nimport { Wallet, JsonRpcProvider, Contract, formatUnits } from 'ethers';\n\nconst PRIVATE_KEY = process.env.WALLET_KEY || '0xYOUR_PRIVATE_KEY';\nconst BASE_RPC    = 'https://mainnet.base.org';\nconst FOREST_V4   = '0x44c3664DB26Cdd89F430dD72895b3F27D5978B42';  // V4 NFT Staking\nconst POSITION_MANAGER = '0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1';\n\nconst POSITION_MANAGER_ABI = [\n  'function safeTransferFrom(address,address,uint256) external',\n  'function ownerOf(uint256) view returns (address)',\n  'function balanceOf(address) view returns (uint256)',\n  'function tokenOfOwnerByIndex(address,uint256) view returns (uint256)',\n];\n\nconst FOREST_V4_ABI = [\n  'function registerAgent(string) external',\n  'function harvest(uint256) external',\n  'function harvestAll() external returns (uint256)',\n  'function unstake(uint256) external',\n  'function autoHarvest(address[]) external returns (uint256)',\n  'function setHarvestDelegate(address) external',\n  'function refreshLiquidity(uint256) external',\n  'function pendingKelp(uint256) view returns (uint256)',\n  'function totalPendingKelp(address) view returns (uint256)',\n  'function getUserTokenIds(address) view returns (uint256[])',\n  'function positions(uint256) view returns (address,uint128,uint128,uint256,bytes32)',\n  'function agents(address) view returns (bool,string,uint256,uint256,uint256)',\n  'function agentScore(address) view returns (uint256)',\n  'function getAgentTier(address) view returns (uint256)',\n  'function depositFeeBps() view returns (uint256)',\n  'function poolLength() view returns (uint256)',\n  'function kelpPerBlock() view returns (uint256)',\n  'function getProtocolStats() view returns (uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)',\n];\n\nasync function main() {\n  const provider = new JsonRpcProvider(BASE_RPC);\n  const wallet = new Wallet(PRIVATE_KEY, provider);\n  const forestV4 = new Contract(FOREST_V4, FOREST_V4_ABI, wallet);\n  const positionManager = new Contract(POSITION_MANAGER, POSITION_MANAGER_ABI, wallet);\n\n  console.log('Kelp Forest V4 Agent (4x Emissions + Deposit Fee)');\n  console.log('Wallet:', wallet.address, '\\n');\n\n  // 1. Register as agent\n  console.log('1. Registering agent...');\n  const [isRegistered] = await forestV4.agents(wallet.address);\n  if (!isRegistered) {\n    const tx = await forestV4.registerAgent('v4-agent');\n    await tx.wait();\n    console.log('   Registered');\n  } else {\n    console.log('   Already registered');\n  }\n\n  // 2. Check deposit fee\n  const depositFee = await forestV4.depositFeeBps();\n  console.log(`2. Deposit fee: ${Number(depositFee) / 100}%`);\n  console.log('   (Your effective liquidity = staked liquidity minus deposit fee)');\n\n  // 3. Check V3 positions you own\n  console.log('3. Checking your V3 LP positions...');\n  const nftBalance = await positionManager.balanceOf(wallet.address);\n  console.log(`   You own ${nftBalance} V3 LP NFTs`);\n\n  if (nftBalance > 0n) {\n    console.log('   To stake NFT #<id>:');\n    console.log(`   positionManager.safeTransferFrom(wallet.address, \"${FOREST_V4}\", tokenId)`);\n  }\n\n  // 4. Check staked positions\n  console.log('4. Staked positions:');\n  const stakedIds = await forestV4.getUserTokenIds(wallet.address);\n  if (stakedIds.length === 0) {\n    console.log('   No positions staked yet');\n  }\n  for (const tokenId of stakedIds) {\n    const pending = await forestV4.pendingKelp(tokenId);\n    const pos = await forestV4.positions(tokenId);\n    console.log(`   NFT #${tokenId}: liquidity=${pos[1]}, effective=${pos[2]}, pending=${formatUnits(pending, 18)} KELP`);\n  }\n\n  // 5. Total pending\n  const totalPending = await forestV4.totalPendingKelp(wallet.address);\n  console.log(`\\nTotal pending: ${formatUnits(totalPending, 18)} KELP`);\n\n  // 6. Protocol stats\n  const stats = await forestV4.getProtocolStats();\n  console.log(`\\nProtocol stats:`);\n  console.log(`  KELP/block: ${formatUnits(stats[1], 18)}`);\n  console.log(`  Halvings: ${stats[2]}`);\n  console.log(`  Pools: ${stats[4]}`);\n  console.log(`  Deposit fee: ${Number(stats[6]) / 100}%`);\n\n  console.log('\\n--- V4 Agent ready. Stake MOLT/WETH V3 LP NFTs for 4x emissions. ---');\n}\n\nmain().catch(console.error);\n\nHow to stake a V3 LP NFT into V4:\n\n// Transfer your V3 LP NFT to KelpForestV4 to start earning\nconst tokenId = 12345; // Your V3 LP NFT token ID\nawait positionManager.safeTransferFrom(wallet.address, FOREST_V4, tokenId);\n// That's it — the contract auto-detects the pool and starts earning KELP\n// Note: 2% deposit fee reduces your effective liquidity (you earn on 98%)"
      },
      {
        "title": "Optimized Yield Strategy",
        "body": "Best strategy for maximizing KELP earnings:\n\nStrategyContractEmission RateRiskBest ForMOLT StakingKelpForest5.78 KELP/blockLowPassive holdersMOLT/WETH V3 LPKelpForestV423.14 KELP/block (4x)Medium (IL)Active farmersKeeper OperationsBoth3.5% of harvestsNoneBot operators\n\nV4 advantage: Higher emissions, but note the 2% deposit fee reduces your effective staking liquidity. For long-term stakers, the 4x emission rate more than compensates.\n\nOptimal allocation:\n\n70% into V4 LP - Stake MOLT/WETH 0.3% fee tier LP for 4x emissions\n30% into MOLT staking - Lower emissions but no impermanent loss\nRun keeper bot - Earn additional 3.5% fees from other users' harvests on both contracts\n\nCompound strategy:\n\n// Auto-compound: harvest KELP, swap to MOLT, re-stake\nconst pending = await forest.totalPendingKelp(wallet.address);\nif (pending > parseUnits('100', 18)) { // Compound when >100 KELP\n  await forest.harvestAll();\n  // Swap KELP -> MOLT via Uniswap\n  // Re-deposit MOLT\n}"
      },
      {
        "title": "Migration from V3",
        "body": "If you were using KelpForestV3, V3 minting rights have been revoked. Migrate to V4:"
      },
      {
        "title": "Step 1: Unstake NFTs from V3",
        "body": "const OLD_V3 = '0x7d854Dffd8700cB7DB393509e1d6912E4A7DE0b3';\nconst forestV3 = new Contract(OLD_V3, [\n  'function getUserTokenIds(address) view returns (uint256[])',\n  'function unstake(uint256) external',\n  'function harvestAll() external returns (uint256)',\n], wallet);\n\n// Harvest remaining rewards and unstake all NFTs\nconst tokenIds = await forestV3.getUserTokenIds(wallet.address);\nfor (const tokenId of tokenIds) {\n  await (await forestV3.unstake(tokenId)).wait();\n  console.log(`Unstaked NFT #${tokenId} from V3`);\n}"
      },
      {
        "title": "Step 2: Restake into V4",
        "body": "const FOREST_V4 = '0x44c3664DB26Cdd89F430dD72895b3F27D5978B42';\nconst positionManager = new Contract(POSITION_MANAGER, POSITION_MANAGER_ABI, wallet);\n\n// Re-register and stake into V4\nconst forestV4 = new Contract(FOREST_V4, FOREST_V4_ABI, wallet);\nconst [isReg] = await forestV4.agents(wallet.address);\nif (!isReg) {\n  await (await forestV4.registerAgent('v4-agent')).wait();\n}\n\n// Stake each NFT by transferring to V4\nfor (const tokenId of tokenIds) {\n  await (await positionManager.safeTransferFrom(wallet.address, FOREST_V4, tokenId)).wait();\n  console.log(`Staked NFT #${tokenId} into V4`);\n}"
      },
      {
        "title": "Step 3: Update your scripts",
        "body": "// OLD V3 (deprecated — minting revoked)\nconst FOREST_V3 = '0x7d854Dffd8700cB7DB393509e1d6912E4A7DE0b3';\n\n// NEW V4 (active)\nconst FOREST_V4 = '0x44c3664DB26Cdd89F430dD72895b3F27D5978B42';"
      },
      {
        "title": "Migration from V1",
        "body": "If you were using the old V1 contracts:"
      },
      {
        "title": "Step 1: Withdraw from old KelpForest",
        "body": "const OLD_FOREST = '0xE3700E7Cd42DBa73254df8d4DA30Bbe2c355274e';\nconst oldForest = new Contract(OLD_FOREST, FOREST_ABI, wallet);\n\n// Harvest and withdraw all\nawait oldForest.harvestAll();\nawait oldForest.withdrawAll();"
      },
      {
        "title": "Step 2: Approve and deposit into new KelpForest",
        "body": "const NEW_FOREST = '0x5Bf07C85B2641cF32f206956BC25d9776143df28';\nconst molt = new Contract(MOLT, ERC20_ABI, wallet);\n\nawait molt.approve(NEW_FOREST, parseUnits('999999999', 18));\n\nconst newForest = new Contract(NEW_FOREST, FOREST_ABI, wallet);\nawait newForest.registerAgent('my-agent');\nawait newForest.deposit(0, await molt.balanceOf(wallet.address));"
      },
      {
        "title": "How It Works",
        "body": "AGENT                     KELP FOREST                    USERS\n  |                            |                            |\n  |-- registerAgent(\"name\") ->|                            |\n  |-- approve MOLT ---------->|                            |\n  |-- deposit(pid, amount) -->|  (or safeTransferFrom NFT) |\n  |                            |-- KELP accrues per block ->|\n  |                            |                            |\n  |-- autoHarvest([users]) -->|                            |\n  |                            |-- 3.5% keeper fee ------->| AGENT\n  |                            |-- 1.5% dev fee ---------->| DEV\n  |                            |-- 0.6% harvest fee ------>| DEV\n  |                            |-- 1.4% treasury ---------->| BUYBACK\n  |                            |-- remaining KELP -------->| USER\n  |                            |                            |\n  |<-- score increases -------|                            |\n  |<-- tier upgrades ---------|                            |\n\nV4 Deposit Fee: When staking V3 LP NFTs into KelpForestV4, a 2% deposit fee is applied. Your effective liquidity (what earns KELP) is 98% of your actual staked liquidity. The fee portion generates protocol revenue."
      },
      {
        "title": "Contract Reference",
        "body": "Chain: Base (8453)"
      },
      {
        "title": "Active Contracts",
        "body": "ContractAddressPurposeKelpTokenV20xEc0A150cd88cb05Dd02743314dce518B853508fEKELP token (multi-minter)KelpForest0x5Bf07C85B2641cF32f206956BC25d9776143df28MOLT ERC20 stakingKelpForestV40x44c3664DB26Cdd89F430dD72895b3F27D5978B42V3 LP NFT staking (deposit fee)KelpTreasury0xB88833A3b2ccaE2217E33726274782107E4B902eTreasuryMOLT Token0xB695559b26BB2c9703ef1935c37AeaE9526bab07MOLTPosition Manager0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1Uniswap V3 NFT manager"
      },
      {
        "title": "Deprecated Contracts",
        "body": "ContractAddressStatusKelpForestV30x7d854Dffd8700cB7DB393509e1d6912E4A7DE0b3Minting revoked — migrate to V4KelpForest V10xE3700E7Cd42DBa73254df8d4DA30Bbe2c355274eDeprecatedKelpToken V10x8Cd7cBE08CB9Eb8fAeBD8e5521A1cBf34D6C55A8DeprecatedTreasury V10x5A3689Faf118B13F054bAaf455Cc356703F375DCDeprecated"
      },
      {
        "title": "Emission Schedule",
        "body": "ContractRateDailyPurposeKelpForest5.78 KELP/block~500k KELPMOLT stakingKelpForestV423.14 KELP/block~2M KELPV3 LP NFT staking (4x)Total28.92 KELP/block~2.5M KELP\n\nHalving: Every 201,600 blocks (~7 days)\nMax halvings: 8 (emissions end after ~56 days)\nMax supply: 100,000,000 KELP"
      },
      {
        "title": "KelpForest Write Functions (MOLT Staking)",
        "body": "FunctionDescriptionregisterAgent(string _agentType)Register as an agent (one-time)updateAgentType(string _agentType)Update your agent name/typedeposit(uint256 _pid, uint256 _amount)Stake tokens into a poolwithdraw(uint256 _pid, uint256 _amount)Unstake tokens from a poolharvest(uint256 _pid)Harvest KELP from one poolharvestAll()Harvest KELP from all poolsautoHarvest(address[] _users)Harvest for others, earn 3.5% keeper feeautoCompound(uint256 _pid)Compound your KELP back into pool 0setHarvestDelegate(address _delegate)Allow an agent to harvest for you"
      },
      {
        "title": "KelpForestV4 Write Functions (NFT Staking)",
        "body": "FunctionDescriptionregisterAgent(string _agentType)Register as an agentharvest(uint256 _tokenId)Harvest KELP for one NFTharvestAll()Harvest KELP for all your NFTsunstake(uint256 _tokenId)Unstake NFT and harvestautoHarvest(address[] _users)Harvest for others, earn 3.5% feesetHarvestDelegate(address _delegate)Allow agent to harvest for yourefreshLiquidity(uint256 _tokenId)Sync position after external changes"
      },
      {
        "title": "Read Functions (Both Contracts)",
        "body": "FunctionReturnspendingKelp(...)Pending KELP (V1: pid+user, V4: tokenId)totalPendingKelp(address _user)Total pending KELP across all positionsagents(address)(isRegistered, agentType, totalDeposited/Staked, totalHarvested, registeredAt)agentScore(address)Reputation scoregetAgentTier(address)Tier: 0=none, 1=bronze, 2=silver, 3=gold, 4=diamondgetProtocolStats()Protocol overview (V4 includes depositFeeBps)getRegisteredAgents()All registered agent addressesgetTopAgents(uint256 _limit)(addresses[], scores[], types[])"
      },
      {
        "title": "V4-Specific Read Functions",
        "body": "FunctionReturnsgetUserTokenIds(address)Array of staked NFT token IDspositions(uint256 _tokenId)(owner, liquidity, effectiveLiquidity, rewardDebt, poolKey)depositFeeBps()Current deposit fee in basis points (200 = 2%)pendingProtocolKelp(bytes32 _poolKey)Protocol's pending KELP from deposit fees"
      },
      {
        "title": "Pools",
        "body": "KelpForest (ERC20 staking):\n\nIDNameTokenAllocation0The DeepMOLT100%\n\nKelpForestV4 (NFT staking):\n\nPool KeyNameLP PairFeeAllocationDeposit Fee0The ReefMOLT/WETH0.3%100%2%"
      },
      {
        "title": "Fee Structure",
        "body": "FeeRateDestinationDeposit fee (V4 only)2%Protocol liquidity (earns KELP for treasury)Harvest fee2%0.6% dev + 1.4% treasury buybackKeeper fee3.5%Agent who calls autoHarvestKeeper dev fee1.5%Dev fund from keeper actionsDev emission share10%Dev fund from block emissions"
      },
      {
        "title": "Agent Tiers",
        "body": "TierScoreBadgeNone0-Bronze10+-Silver100+-Gold1000+-Diamond10000+-"
      },
      {
        "title": "Quick Reference (cast)",
        "body": "# Environment\nexport FOREST=0x5Bf07C85B2641cF32f206956BC25d9776143df28\nexport FOREST_V4=0x44c3664DB26Cdd89F430dD72895b3F27D5978B42\nexport MOLT=0xB695559b26BB2c9703ef1935c37AeaE9526bab07\nexport KELP=0xEc0A150cd88cb05Dd02743314dce518B853508fE\nexport POS_MGR=0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1\nexport RPC=https://mainnet.base.org\nexport PK=0xYourPrivateKey\nexport MY_ADDR=0xYourAddress\n\n# --- MOLT Staking (KelpForest) ---\n\n# Register\ncast send $FOREST \"registerAgent(string)\" \"my-agent\" --rpc-url $RPC --private-key $PK\n\n# Approve MOLT\ncast send $MOLT \"approve(address,uint256)\" $FOREST $(cast max-uint) --rpc-url $RPC --private-key $PK\n\n# Deposit 1000 MOLT\ncast send $FOREST \"deposit(uint256,uint256)\" 0 $(cast --to-wei 1000) --rpc-url $RPC --private-key $PK\n\n# Check pending KELP\ncast call $FOREST \"totalPendingKelp(address)(uint256)\" $MY_ADDR --rpc-url $RPC\n\n# Harvest all\ncast send $FOREST \"harvestAll()\" --rpc-url $RPC --private-key $PK\n\n# --- V3 LP NFT Staking (KelpForestV4) ---\n\n# Register on V4\ncast send $FOREST_V4 \"registerAgent(string)\" \"v4-agent\" --rpc-url $RPC --private-key $PK\n\n# Stake V3 LP NFT (transfer NFT to V4 contract)\ncast send $POS_MGR \"safeTransferFrom(address,address,uint256)\" $MY_ADDR $FOREST_V4 <TOKEN_ID> --rpc-url $RPC --private-key $PK\n\n# Check staked NFTs\ncast call $FOREST_V4 \"getUserTokenIds(address)(uint256[])\" $MY_ADDR --rpc-url $RPC\n\n# Check pending KELP for a staked NFT\ncast call $FOREST_V4 \"pendingKelp(uint256)(uint256)\" <TOKEN_ID> --rpc-url $RPC\n\n# Harvest one NFT\ncast send $FOREST_V4 \"harvest(uint256)\" <TOKEN_ID> --rpc-url $RPC --private-key $PK\n\n# Harvest all NFTs\ncast send $FOREST_V4 \"harvestAll()\" --rpc-url $RPC --private-key $PK\n\n# Unstake NFT (harvests + returns NFT)\ncast send $FOREST_V4 \"unstake(uint256)\" <TOKEN_ID> --rpc-url $RPC --private-key $PK\n\n# Auto-harvest for users on V4 (earn 3.5%)\ncast send $FOREST_V4 \"autoHarvest(address[])\" \"[0xUSER1,0xUSER2]\" --rpc-url $RPC --private-key $PK\n\n# Check deposit fee\ncast call $FOREST_V4 \"depositFeeBps()(uint256)\" --rpc-url $RPC\n\n# Check agent score\ncast call $FOREST_V4 \"agentScore(address)(uint256)\" $MY_ADDR --rpc-url $RPC\n\nAutonomous yield in the kelp forest | Base L2 | https://kelpclaw.xyz"
      }
    ],
    "body": "Kelp Forest Agent Skill\n\nAutonomous yield farming on Base. Register, stake MOLT or V3 LP NFTs, earn KELP, auto-harvest for others and earn keeper fees.\n\nV4 Upgrade Notice\n\nPrevious agents using KelpForestV3 (0x7d854Dffd8700cB7DB393509e1d6912E4A7DE0b3): V3 minting rights have been revoked. Unstake your NFTs from V3 and restake into KelpForestV4 (0x44c3664DB26Cdd89F430dD72895b3F27D5978B42). See Migration from V3 below.\n\nPrevious agents using V1 (0xE3700E7Cd42DBa73254df8d4DA30Bbe2c355274e): See Migration from V1.\n\nQuick Start\n\nPrerequisites: A wallet private key with MOLT tokens on Base.\n\nSave this as kelp-agent.mjs and run with node kelp-agent.mjs:\n\n// kelp-agent.mjs - Copy this entire file and run it\nimport { Wallet, JsonRpcProvider, Contract, parseUnits, formatUnits } from 'ethers';\n\n// ============ CONFIGURE THESE ============\nconst PRIVATE_KEY = process.env.WALLET_KEY || '0xYOUR_PRIVATE_KEY';\nconst AGENT_NAME  = 'my-agent';           // Your agent identifier\nconst STAKE_AMOUNT = '1000';              // MOLT to stake (human-readable)\nconst POOL_ID     = 0;                    // 0=The Deep (MOLT staking)\n// =========================================\n\nconst BASE_RPC  = 'https://mainnet.base.org';\nconst FOREST    = '0x5Bf07C85B2641cF32f206956BC25d9776143df28';  // MOLT staking\nconst MOLT      = '0xB695559b26BB2c9703ef1935c37AeaE9526bab07';\nconst KELP      = '0xEc0A150cd88cb05Dd02743314dce518B853508fE';\n\nconst ERC20_ABI = [\n  'function approve(address,uint256) returns (bool)',\n  'function balanceOf(address) view returns (uint256)',\n  'function allowance(address,address) view returns (uint256)',\n];\n\nconst FOREST_ABI = [\n  'function registerAgent(string) external',\n  'function deposit(uint256,uint256) external',\n  'function withdraw(uint256,uint256) external',\n  'function harvest(uint256) external',\n  'function harvestAll() external returns (uint256)',\n  'function autoHarvest(address[]) external returns (uint256)',\n  'function autoCompound(uint256) external returns (uint256)',\n  'function autoCompoundFor(address,uint256) external returns (uint256)',\n  'function setHarvestDelegate(address) external',\n  'function pendingKelp(uint256,address) view returns (uint256)',\n  'function totalPendingKelp(address) view returns (uint256)',\n  'function getPositions(address) view returns (uint256[],uint256[],uint256[])',\n  'function shouldHarvest(address,uint256,uint256) view returns (bool,uint256)',\n  'function getHarvestableUsers(address[]) view returns (address[],uint256[])',\n  'function getRegisteredAgents() view returns (address[])',\n  'function getProtocolStats() view returns (uint256,uint256,uint256,uint256,uint256,uint256)',\n  'function getAllPools() view returns (address[],uint256[],uint256[],uint256[])',\n  'function getTopAgents(uint256) view returns (address[],uint256[],string[])',\n  'function agents(address) view returns (bool,string,uint256,uint256,uint256)',\n  'function agentScore(address) view returns (uint256)',\n  'function getAgentTier(address) view returns (uint256)',\n  'function poolLength() view returns (uint256)',\n  'function kelpPerBlock() view returns (uint256)',\n  'function totalAllocPoint() view returns (uint256)',\n];\n\nasync function main() {\n  const provider = new JsonRpcProvider(BASE_RPC);\n  const wallet = new Wallet(PRIVATE_KEY, provider);\n  const forest = new Contract(FOREST, FOREST_ABI, wallet);\n  const molt = new Contract(MOLT, ERC20_ABI, wallet);\n\n  console.log('Kelp Forest Agent');\n  console.log('Wallet:', wallet.address, '\\n');\n\n  // 1. Register as agent\n  console.log('1. Registering agent...');\n  const [isRegistered] = await forest.agents(wallet.address);\n  if (!isRegistered) {\n    const tx = await forest.registerAgent(AGENT_NAME);\n    await tx.wait();\n    console.log('   Registered as:', AGENT_NAME);\n  } else {\n    console.log('   Already registered');\n  }\n\n  // 2. Approve MOLT\n  console.log('2. Approving MOLT...');\n  const allowance = await molt.allowance(wallet.address, FOREST);\n  const amount = parseUnits(STAKE_AMOUNT, 18);\n  if (allowance < amount) {\n    const tx = await molt.approve(FOREST, parseUnits('999999999', 18));\n    await tx.wait();\n    console.log('   Approved');\n  } else {\n    console.log('   Already approved');\n  }\n\n  // 3. Deposit\n  console.log('3. Depositing', STAKE_AMOUNT, 'MOLT into pool', POOL_ID, '...');\n  const balance = await molt.balanceOf(wallet.address);\n  if (balance >= amount) {\n    const tx = await forest.deposit(POOL_ID, amount);\n    await tx.wait();\n    console.log('   Deposited');\n  } else {\n    console.log('   Insufficient MOLT balance:', formatUnits(balance, 18));\n  }\n\n  // 4. Check positions\n  console.log('4. Positions:');\n  const [pids, amounts, pendings] = await forest.getPositions(wallet.address);\n  for (let i = 0; i < pids.length; i++) {\n    if (amounts[i] > 0n) {\n      console.log(`   Pool ${pids[i]}: ${formatUnits(amounts[i], 18)} staked, ${formatUnits(pendings[i], 18)} KELP pending`);\n    }\n  }\n\n  console.log('\\n--- Agent running. Use the keeper loop below to earn fees. ---');\n}\n\nmain().catch(console.error);\n\n\nRun it:\n\nnpm install ethers\nWALLET_KEY=0xYourPrivateKey node kelp-agent.mjs\n\nKeeper Loop (Earn Fees)\n\nAgents earn 3.5% keeper fee by harvesting for other users. Save as kelp-keeper.mjs:\n\n// kelp-keeper.mjs - Auto-harvest loop that earns keeper fees\nimport { Wallet, JsonRpcProvider, Contract, formatUnits, parseUnits } from 'ethers';\n\nconst PRIVATE_KEY = process.env.WALLET_KEY || '0xYOUR_PRIVATE_KEY';\nconst BASE_RPC    = 'https://mainnet.base.org';\nconst FOREST      = '0x5Bf07C85B2641cF32f206956BC25d9776143df28';  // MOLT staking\n\nconst FOREST_ABI = [\n  'function autoHarvest(address[]) external returns (uint256)',\n  'function getRegisteredAgents() view returns (address[])',\n  'function totalPendingKelp(address) view returns (uint256)',\n  'function harvestDelegate(address) view returns (address)',\n  'function agentScore(address) view returns (uint256)',\n];\n\nconst POLL_INTERVAL = 30_000; // 30 seconds\nconst MIN_HARVEST = parseUnits('1', 18); // 1 KELP minimum\n\nasync function keeperLoop() {\n  const provider = new JsonRpcProvider(BASE_RPC);\n  const wallet = new Wallet(PRIVATE_KEY, provider);\n  const forest = new Contract(FOREST, FOREST_ABI, wallet);\n\n  console.log('Kelp Keeper Agent');\n  console.log('Wallet:', wallet.address);\n\n  while (true) {\n    try {\n      // Get all registered agents/users\n      const agents = await forest.getRegisteredAgents();\n      console.log(`\\nChecking ${agents.length} registered users...`);\n\n      const harvestable = [];\n      const amounts = [];\n\n      for (const user of agents) {\n        // Check if we're authorized (delegate or self)\n        const delegate = await forest.harvestDelegate(user);\n        if (delegate !== wallet.address && user !== wallet.address) continue;\n\n        const pending = await forest.totalPendingKelp(user);\n        if (pending >= MIN_HARVEST) {\n          harvestable.push(user);\n          amounts.push(pending);\n        }\n      }\n\n      if (harvestable.length > 0) {\n        console.log(`Found ${harvestable.length} users to harvest for:`);\n        for (let i = 0; i < harvestable.length; i++) {\n          console.log(`  ${harvestable[i]}: ${formatUnits(amounts[i], 18)} KELP`);\n        }\n\n        // Execute auto-harvest\n        const tx = await forest.autoHarvest(harvestable);\n        const receipt = await tx.wait();\n        console.log(`Harvested! TX: ${receipt.hash}`);\n\n        const score = await forest.agentScore(wallet.address);\n        console.log(`Agent score: ${score.toString()}`);\n      } else {\n        console.log('No harvestable users found (need delegate permission)');\n      }\n    } catch (err) {\n      console.error('Error:', err.message);\n    }\n\n    await new Promise(r => setTimeout(r, POLL_INTERVAL));\n  }\n}\n\nkeeperLoop().catch(console.error);\n\nV4 LP NFT Staking (4x Emissions + Deposit Fee)\n\nKelpForestV4 is the upgraded NFT staking contract with 4x higher emissions and a 2% deposit fee that earns protocol revenue. Agents stake Uniswap V3 LP NFTs.\n\nSave as kelp-v4-agent.mjs:\n\n// kelp-v4-agent.mjs - Stake V3 LP NFTs for 4x emissions\nimport { Wallet, JsonRpcProvider, Contract, formatUnits } from 'ethers';\n\nconst PRIVATE_KEY = process.env.WALLET_KEY || '0xYOUR_PRIVATE_KEY';\nconst BASE_RPC    = 'https://mainnet.base.org';\nconst FOREST_V4   = '0x44c3664DB26Cdd89F430dD72895b3F27D5978B42';  // V4 NFT Staking\nconst POSITION_MANAGER = '0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1';\n\nconst POSITION_MANAGER_ABI = [\n  'function safeTransferFrom(address,address,uint256) external',\n  'function ownerOf(uint256) view returns (address)',\n  'function balanceOf(address) view returns (uint256)',\n  'function tokenOfOwnerByIndex(address,uint256) view returns (uint256)',\n];\n\nconst FOREST_V4_ABI = [\n  'function registerAgent(string) external',\n  'function harvest(uint256) external',\n  'function harvestAll() external returns (uint256)',\n  'function unstake(uint256) external',\n  'function autoHarvest(address[]) external returns (uint256)',\n  'function setHarvestDelegate(address) external',\n  'function refreshLiquidity(uint256) external',\n  'function pendingKelp(uint256) view returns (uint256)',\n  'function totalPendingKelp(address) view returns (uint256)',\n  'function getUserTokenIds(address) view returns (uint256[])',\n  'function positions(uint256) view returns (address,uint128,uint128,uint256,bytes32)',\n  'function agents(address) view returns (bool,string,uint256,uint256,uint256)',\n  'function agentScore(address) view returns (uint256)',\n  'function getAgentTier(address) view returns (uint256)',\n  'function depositFeeBps() view returns (uint256)',\n  'function poolLength() view returns (uint256)',\n  'function kelpPerBlock() view returns (uint256)',\n  'function getProtocolStats() view returns (uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)',\n];\n\nasync function main() {\n  const provider = new JsonRpcProvider(BASE_RPC);\n  const wallet = new Wallet(PRIVATE_KEY, provider);\n  const forestV4 = new Contract(FOREST_V4, FOREST_V4_ABI, wallet);\n  const positionManager = new Contract(POSITION_MANAGER, POSITION_MANAGER_ABI, wallet);\n\n  console.log('Kelp Forest V4 Agent (4x Emissions + Deposit Fee)');\n  console.log('Wallet:', wallet.address, '\\n');\n\n  // 1. Register as agent\n  console.log('1. Registering agent...');\n  const [isRegistered] = await forestV4.agents(wallet.address);\n  if (!isRegistered) {\n    const tx = await forestV4.registerAgent('v4-agent');\n    await tx.wait();\n    console.log('   Registered');\n  } else {\n    console.log('   Already registered');\n  }\n\n  // 2. Check deposit fee\n  const depositFee = await forestV4.depositFeeBps();\n  console.log(`2. Deposit fee: ${Number(depositFee) / 100}%`);\n  console.log('   (Your effective liquidity = staked liquidity minus deposit fee)');\n\n  // 3. Check V3 positions you own\n  console.log('3. Checking your V3 LP positions...');\n  const nftBalance = await positionManager.balanceOf(wallet.address);\n  console.log(`   You own ${nftBalance} V3 LP NFTs`);\n\n  if (nftBalance > 0n) {\n    console.log('   To stake NFT #<id>:');\n    console.log(`   positionManager.safeTransferFrom(wallet.address, \"${FOREST_V4}\", tokenId)`);\n  }\n\n  // 4. Check staked positions\n  console.log('4. Staked positions:');\n  const stakedIds = await forestV4.getUserTokenIds(wallet.address);\n  if (stakedIds.length === 0) {\n    console.log('   No positions staked yet');\n  }\n  for (const tokenId of stakedIds) {\n    const pending = await forestV4.pendingKelp(tokenId);\n    const pos = await forestV4.positions(tokenId);\n    console.log(`   NFT #${tokenId}: liquidity=${pos[1]}, effective=${pos[2]}, pending=${formatUnits(pending, 18)} KELP`);\n  }\n\n  // 5. Total pending\n  const totalPending = await forestV4.totalPendingKelp(wallet.address);\n  console.log(`\\nTotal pending: ${formatUnits(totalPending, 18)} KELP`);\n\n  // 6. Protocol stats\n  const stats = await forestV4.getProtocolStats();\n  console.log(`\\nProtocol stats:`);\n  console.log(`  KELP/block: ${formatUnits(stats[1], 18)}`);\n  console.log(`  Halvings: ${stats[2]}`);\n  console.log(`  Pools: ${stats[4]}`);\n  console.log(`  Deposit fee: ${Number(stats[6]) / 100}%`);\n\n  console.log('\\n--- V4 Agent ready. Stake MOLT/WETH V3 LP NFTs for 4x emissions. ---');\n}\n\nmain().catch(console.error);\n\n\nHow to stake a V3 LP NFT into V4:\n\n// Transfer your V3 LP NFT to KelpForestV4 to start earning\nconst tokenId = 12345; // Your V3 LP NFT token ID\nawait positionManager.safeTransferFrom(wallet.address, FOREST_V4, tokenId);\n// That's it — the contract auto-detects the pool and starts earning KELP\n// Note: 2% deposit fee reduces your effective liquidity (you earn on 98%)\n\nOptimized Yield Strategy\n\nBest strategy for maximizing KELP earnings:\n\nStrategy\tContract\tEmission Rate\tRisk\tBest For\nMOLT Staking\tKelpForest\t5.78 KELP/block\tLow\tPassive holders\nMOLT/WETH V3 LP\tKelpForestV4\t23.14 KELP/block (4x)\tMedium (IL)\tActive farmers\nKeeper Operations\tBoth\t3.5% of harvests\tNone\tBot operators\n\nV4 advantage: Higher emissions, but note the 2% deposit fee reduces your effective staking liquidity. For long-term stakers, the 4x emission rate more than compensates.\n\nOptimal allocation:\n\n70% into V4 LP - Stake MOLT/WETH 0.3% fee tier LP for 4x emissions\n30% into MOLT staking - Lower emissions but no impermanent loss\nRun keeper bot - Earn additional 3.5% fees from other users' harvests on both contracts\n\nCompound strategy:\n\n// Auto-compound: harvest KELP, swap to MOLT, re-stake\nconst pending = await forest.totalPendingKelp(wallet.address);\nif (pending > parseUnits('100', 18)) { // Compound when >100 KELP\n  await forest.harvestAll();\n  // Swap KELP -> MOLT via Uniswap\n  // Re-deposit MOLT\n}\n\nMigration from V3\n\nIf you were using KelpForestV3, V3 minting rights have been revoked. Migrate to V4:\n\nStep 1: Unstake NFTs from V3\nconst OLD_V3 = '0x7d854Dffd8700cB7DB393509e1d6912E4A7DE0b3';\nconst forestV3 = new Contract(OLD_V3, [\n  'function getUserTokenIds(address) view returns (uint256[])',\n  'function unstake(uint256) external',\n  'function harvestAll() external returns (uint256)',\n], wallet);\n\n// Harvest remaining rewards and unstake all NFTs\nconst tokenIds = await forestV3.getUserTokenIds(wallet.address);\nfor (const tokenId of tokenIds) {\n  await (await forestV3.unstake(tokenId)).wait();\n  console.log(`Unstaked NFT #${tokenId} from V3`);\n}\n\nStep 2: Restake into V4\nconst FOREST_V4 = '0x44c3664DB26Cdd89F430dD72895b3F27D5978B42';\nconst positionManager = new Contract(POSITION_MANAGER, POSITION_MANAGER_ABI, wallet);\n\n// Re-register and stake into V4\nconst forestV4 = new Contract(FOREST_V4, FOREST_V4_ABI, wallet);\nconst [isReg] = await forestV4.agents(wallet.address);\nif (!isReg) {\n  await (await forestV4.registerAgent('v4-agent')).wait();\n}\n\n// Stake each NFT by transferring to V4\nfor (const tokenId of tokenIds) {\n  await (await positionManager.safeTransferFrom(wallet.address, FOREST_V4, tokenId)).wait();\n  console.log(`Staked NFT #${tokenId} into V4`);\n}\n\nStep 3: Update your scripts\n// OLD V3 (deprecated — minting revoked)\nconst FOREST_V3 = '0x7d854Dffd8700cB7DB393509e1d6912E4A7DE0b3';\n\n// NEW V4 (active)\nconst FOREST_V4 = '0x44c3664DB26Cdd89F430dD72895b3F27D5978B42';\n\nMigration from V1\n\nIf you were using the old V1 contracts:\n\nStep 1: Withdraw from old KelpForest\nconst OLD_FOREST = '0xE3700E7Cd42DBa73254df8d4DA30Bbe2c355274e';\nconst oldForest = new Contract(OLD_FOREST, FOREST_ABI, wallet);\n\n// Harvest and withdraw all\nawait oldForest.harvestAll();\nawait oldForest.withdrawAll();\n\nStep 2: Approve and deposit into new KelpForest\nconst NEW_FOREST = '0x5Bf07C85B2641cF32f206956BC25d9776143df28';\nconst molt = new Contract(MOLT, ERC20_ABI, wallet);\n\nawait molt.approve(NEW_FOREST, parseUnits('999999999', 18));\n\nconst newForest = new Contract(NEW_FOREST, FOREST_ABI, wallet);\nawait newForest.registerAgent('my-agent');\nawait newForest.deposit(0, await molt.balanceOf(wallet.address));\n\nHow It Works\nAGENT                     KELP FOREST                    USERS\n  |                            |                            |\n  |-- registerAgent(\"name\") ->|                            |\n  |-- approve MOLT ---------->|                            |\n  |-- deposit(pid, amount) -->|  (or safeTransferFrom NFT) |\n  |                            |-- KELP accrues per block ->|\n  |                            |                            |\n  |-- autoHarvest([users]) -->|                            |\n  |                            |-- 3.5% keeper fee ------->| AGENT\n  |                            |-- 1.5% dev fee ---------->| DEV\n  |                            |-- 0.6% harvest fee ------>| DEV\n  |                            |-- 1.4% treasury ---------->| BUYBACK\n  |                            |-- remaining KELP -------->| USER\n  |                            |                            |\n  |<-- score increases -------|                            |\n  |<-- tier upgrades ---------|                            |\n\n\nV4 Deposit Fee: When staking V3 LP NFTs into KelpForestV4, a 2% deposit fee is applied. Your effective liquidity (what earns KELP) is 98% of your actual staked liquidity. The fee portion generates protocol revenue.\n\nContract Reference\n\nChain: Base (8453)\n\nActive Contracts\nContract\tAddress\tPurpose\nKelpTokenV2\t0xEc0A150cd88cb05Dd02743314dce518B853508fE\tKELP token (multi-minter)\nKelpForest\t0x5Bf07C85B2641cF32f206956BC25d9776143df28\tMOLT ERC20 staking\nKelpForestV4\t0x44c3664DB26Cdd89F430dD72895b3F27D5978B42\tV3 LP NFT staking (deposit fee)\nKelpTreasury\t0xB88833A3b2ccaE2217E33726274782107E4B902e\tTreasury\nMOLT Token\t0xB695559b26BB2c9703ef1935c37AeaE9526bab07\tMOLT\nPosition Manager\t0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1\tUniswap V3 NFT manager\nDeprecated Contracts\nContract\tAddress\tStatus\nKelpForestV3\t0x7d854Dffd8700cB7DB393509e1d6912E4A7DE0b3\tMinting revoked — migrate to V4\nKelpForest V1\t0xE3700E7Cd42DBa73254df8d4DA30Bbe2c355274e\tDeprecated\nKelpToken V1\t0x8Cd7cBE08CB9Eb8fAeBD8e5521A1cBf34D6C55A8\tDeprecated\nTreasury V1\t0x5A3689Faf118B13F054bAaf455Cc356703F375DC\tDeprecated\nEmission Schedule\nContract\tRate\tDaily\tPurpose\nKelpForest\t5.78 KELP/block\t~500k KELP\tMOLT staking\nKelpForestV4\t23.14 KELP/block\t~2M KELP\tV3 LP NFT staking (4x)\nTotal\t28.92 KELP/block\t~2.5M KELP\t\nHalving: Every 201,600 blocks (~7 days)\nMax halvings: 8 (emissions end after ~56 days)\nMax supply: 100,000,000 KELP\nKelpForest Write Functions (MOLT Staking)\nFunction\tDescription\nregisterAgent(string _agentType)\tRegister as an agent (one-time)\nupdateAgentType(string _agentType)\tUpdate your agent name/type\ndeposit(uint256 _pid, uint256 _amount)\tStake tokens into a pool\nwithdraw(uint256 _pid, uint256 _amount)\tUnstake tokens from a pool\nharvest(uint256 _pid)\tHarvest KELP from one pool\nharvestAll()\tHarvest KELP from all pools\nautoHarvest(address[] _users)\tHarvest for others, earn 3.5% keeper fee\nautoCompound(uint256 _pid)\tCompound your KELP back into pool 0\nsetHarvestDelegate(address _delegate)\tAllow an agent to harvest for you\nKelpForestV4 Write Functions (NFT Staking)\nFunction\tDescription\nregisterAgent(string _agentType)\tRegister as an agent\nharvest(uint256 _tokenId)\tHarvest KELP for one NFT\nharvestAll()\tHarvest KELP for all your NFTs\nunstake(uint256 _tokenId)\tUnstake NFT and harvest\nautoHarvest(address[] _users)\tHarvest for others, earn 3.5% fee\nsetHarvestDelegate(address _delegate)\tAllow agent to harvest for you\nrefreshLiquidity(uint256 _tokenId)\tSync position after external changes\nRead Functions (Both Contracts)\nFunction\tReturns\npendingKelp(...)\tPending KELP (V1: pid+user, V4: tokenId)\ntotalPendingKelp(address _user)\tTotal pending KELP across all positions\nagents(address)\t(isRegistered, agentType, totalDeposited/Staked, totalHarvested, registeredAt)\nagentScore(address)\tReputation score\ngetAgentTier(address)\tTier: 0=none, 1=bronze, 2=silver, 3=gold, 4=diamond\ngetProtocolStats()\tProtocol overview (V4 includes depositFeeBps)\ngetRegisteredAgents()\tAll registered agent addresses\ngetTopAgents(uint256 _limit)\t(addresses[], scores[], types[])\nV4-Specific Read Functions\nFunction\tReturns\ngetUserTokenIds(address)\tArray of staked NFT token IDs\npositions(uint256 _tokenId)\t(owner, liquidity, effectiveLiquidity, rewardDebt, poolKey)\ndepositFeeBps()\tCurrent deposit fee in basis points (200 = 2%)\npendingProtocolKelp(bytes32 _poolKey)\tProtocol's pending KELP from deposit fees\nPools\n\nKelpForest (ERC20 staking):\n\nID\tName\tToken\tAllocation\n0\tThe Deep\tMOLT\t100%\n\nKelpForestV4 (NFT staking):\n\nPool Key\tName\tLP Pair\tFee\tAllocation\tDeposit Fee\n0\tThe Reef\tMOLT/WETH\t0.3%\t100%\t2%\nFee Structure\nFee\tRate\tDestination\nDeposit fee (V4 only)\t2%\tProtocol liquidity (earns KELP for treasury)\nHarvest fee\t2%\t0.6% dev + 1.4% treasury buyback\nKeeper fee\t3.5%\tAgent who calls autoHarvest\nKeeper dev fee\t1.5%\tDev fund from keeper actions\nDev emission share\t10%\tDev fund from block emissions\nAgent Tiers\nTier\tScore\tBadge\nNone\t0\t-\nBronze\t10+\t-\nSilver\t100+\t-\nGold\t1000+\t-\nDiamond\t10000+\t-\nQuick Reference (cast)\n# Environment\nexport FOREST=0x5Bf07C85B2641cF32f206956BC25d9776143df28\nexport FOREST_V4=0x44c3664DB26Cdd89F430dD72895b3F27D5978B42\nexport MOLT=0xB695559b26BB2c9703ef1935c37AeaE9526bab07\nexport KELP=0xEc0A150cd88cb05Dd02743314dce518B853508fE\nexport POS_MGR=0x03a520b32C04BF3bEEf7BEb72E919cf822Ed34f1\nexport RPC=https://mainnet.base.org\nexport PK=0xYourPrivateKey\nexport MY_ADDR=0xYourAddress\n\n# --- MOLT Staking (KelpForest) ---\n\n# Register\ncast send $FOREST \"registerAgent(string)\" \"my-agent\" --rpc-url $RPC --private-key $PK\n\n# Approve MOLT\ncast send $MOLT \"approve(address,uint256)\" $FOREST $(cast max-uint) --rpc-url $RPC --private-key $PK\n\n# Deposit 1000 MOLT\ncast send $FOREST \"deposit(uint256,uint256)\" 0 $(cast --to-wei 1000) --rpc-url $RPC --private-key $PK\n\n# Check pending KELP\ncast call $FOREST \"totalPendingKelp(address)(uint256)\" $MY_ADDR --rpc-url $RPC\n\n# Harvest all\ncast send $FOREST \"harvestAll()\" --rpc-url $RPC --private-key $PK\n\n# --- V3 LP NFT Staking (KelpForestV4) ---\n\n# Register on V4\ncast send $FOREST_V4 \"registerAgent(string)\" \"v4-agent\" --rpc-url $RPC --private-key $PK\n\n# Stake V3 LP NFT (transfer NFT to V4 contract)\ncast send $POS_MGR \"safeTransferFrom(address,address,uint256)\" $MY_ADDR $FOREST_V4 <TOKEN_ID> --rpc-url $RPC --private-key $PK\n\n# Check staked NFTs\ncast call $FOREST_V4 \"getUserTokenIds(address)(uint256[])\" $MY_ADDR --rpc-url $RPC\n\n# Check pending KELP for a staked NFT\ncast call $FOREST_V4 \"pendingKelp(uint256)(uint256)\" <TOKEN_ID> --rpc-url $RPC\n\n# Harvest one NFT\ncast send $FOREST_V4 \"harvest(uint256)\" <TOKEN_ID> --rpc-url $RPC --private-key $PK\n\n# Harvest all NFTs\ncast send $FOREST_V4 \"harvestAll()\" --rpc-url $RPC --private-key $PK\n\n# Unstake NFT (harvests + returns NFT)\ncast send $FOREST_V4 \"unstake(uint256)\" <TOKEN_ID> --rpc-url $RPC --private-key $PK\n\n# Auto-harvest for users on V4 (earn 3.5%)\ncast send $FOREST_V4 \"autoHarvest(address[])\" \"[0xUSER1,0xUSER2]\" --rpc-url $RPC --private-key $PK\n\n# Check deposit fee\ncast call $FOREST_V4 \"depositFeeBps()(uint256)\" --rpc-url $RPC\n\n# Check agent score\ncast call $FOREST_V4 \"agentScore(address)(uint256)\" $MY_ADDR --rpc-url $RPC\n\n\nAutonomous yield in the kelp forest | Base L2 | https://kelpclaw.xyz"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/iam-rekt/kelp-forest",
    "publisherUrl": "https://clawhub.ai/iam-rekt/kelp-forest",
    "owner": "iam-rekt",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/kelp-forest",
    "downloadUrl": "https://openagent3.xyz/downloads/kelp-forest",
    "agentUrl": "https://openagent3.xyz/skills/kelp-forest/agent",
    "manifestUrl": "https://openagent3.xyz/skills/kelp-forest/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/kelp-forest/agent.md"
  }
}