Geode Document Hub
  • Geode Document Hub
  • The Staking Library
    • 🔥The Issue
    • 🧯A Solution
  • Operator Marketplace
    • 🟢A Validator's Lifecycle
    • 🔵Maintenance Fee
    • 🟡Onboarding New Operators
    • 🔴Regulating the Marketplace
      • 🚨Prison
  • Key Concepts
    • 🪙Staking Derivatives
      • G-Derivatives
        • gETH vs gAVAX
    • 🌀Portal
      • 🔐Isolated Storage
      • 🤝Dual Governance
      • ⚠️Limited Upgradability
    • ⚙️Permissionless Configurable Staking Pools
      • 🎭Current Interfaces
      • ⛏️Maintainers
    • 🛡️Withdrawal Contracts
      • ⛑️Recovery Mode
      • 🕗Withdrawal Queue
    • 🌊Bound Liquidity Pools
    • 🔭Oracles
      • Telescope Ether
      • Telescope Avax
    • 👾Future of Geode
      • Better Maintainers (WIP)
      • Synthetic Liquidity (WIP)
      • Dynamic Withdrawals (WIP)
      • Further Decentralization
        • Supporting EIP-4788 (DRAFT)
        • Quadratic Weighted Senate (DRAFT)
        • Degen Operators (DRAFT)
        • Decentralized Telescope (DRAFT)
      • Chain Sync (AVAX) (draft)
  • Ethereum Guides
    • 📗Staking Pool HandBook
      • Initiating a Customizable Staking Pool
      • Managing Your Operator Set
      • Changing Your Pool's Owner
      • Manage Your Maintenance Fee
      • Private Pools and Whitelisting
      • Using a Bound Liquidity Pool
      • Using Maintainers for Your Pool
      • Securing Your Withdrawal Contract
      • Decentralizing Your Pool
    • 📕Operator Handbook
      • Get Onboarded
      • Initiating an Operator
      • Communicating with Portal
      • Creating Validators
      • Changing an Operator's Owner
      • Switching Your Fee
      • Switching Your Validator Period
      • Using Maintainers
      • Optimizing Your Revenue
      • Exiting Validators
    • 📘Liquidity Pool HandBook
  • Avalanche Guides
    • Staking Pool Handbook
    • Operator Handbook
  • Developers
    • Networks
    • Live Contracts
      • Avalanche v1
      • Ethereum v2
        • gETH.sol
        • Portal.sol
          • globals.sol
          • DataStoreUtilsLib.sol
          • GeodeUtilsLib.sol
          • DepositContractUtilsLib.sol
          • OracleUtilsLib.sol
          • StakeUtilsLib.sol
        • Swap.sol
          • AmplificationUtils.sol
          • MathUtils.sol
          • SwapUtils.sol
          • LPToken.sol
        • WithdrawalContract.sol
        • Interfaces
          • ERC20InterfaceUpgaradable.sol
          • ERC20InterfacePermitUpgradable.sol
    • Audits
    • Bug Bounties
Powered by GitBook
On this page
  • Before Initiation:
  • 32 Ether
  • Pool ID
  • Maintainers
  • Initiate Your Pool!
  • Example of Pool Creation Transaction
  • Basic Pool Initiation
  • Complex Initiation
  1. Ethereum Guides
  2. Staking Pool HandBook

Initiating a Customizable Staking Pool

PreviousStaking Pool HandBookNextManaging Your Operator Set

Last updated 2 years ago

Before Initiation:

32 Ether

Creating a Pool is permissionless, anyone can claim any pool name.

To prevent sybil attacks, initiation requires exactly 1 validator worth of funds. However, you can deposit more Ether later.

However, this amount will be used to create your first validator.

Pool ID

Every Pool will have a unique ID.

It will be used for your Pool operations, and you can find your ID from both our frontend or Portal.

const pool_ID = Portal.generateId(pool_name, 5);

Maintainers

Maintainers are useful to automate pool owners' daily tasks, such as choosing your Node Operators.

Initiate Your Pool!

Geode uses an initiator function to set some parameters for your staking pool and derivative.

Portal.initiatePool(
    NAME,
    fee,
    interfaceVersion,
    maintainer,
    interface_data,
    config,
    {value: 32 Ether}
);
  1. NAME: Unique name of your Pool. Can not be changed later.

  2. FEE: Maintenance fee that will be charged for your services as the pool owner. 10^10 represents 100%, can be set to up to 10% (10^9). Can be changed later.

  3. Interface Version: Can be empty, or can be any interfaces from the list below. Can not be changed later.

  1. Maintainer: Any other address that will manage your pool's Node Operators. Can be a community owned Maintainer, or the address of an automation script, etc. Can be changed later.

  2. Interface Data: some interfaces require data to be present along with a gETH address and Pool id.

  3. Config: initial configuration of your Pool as:

    1. True if a private pool - Can be changed later.

    2. True if uses an interface. Can not be changed later.

    3. True if uses a liquidity Pool - Can be changed later.

Note that, if you create private pool, you will need to create a Whitelisting Contract and register it.

However, Pool CONTROLLERs are allowed to use the pool even without creating and registering a contract.

Example of Pool Creation Transaction

Basic Pool Initiation

The below transaction creates a Private Staking Pool with no maintenance fee, no interface, and no Liquidity Pool:

// Pool
const your_address="0xabcdf....abcdf";
const pool_name= "IceBear's Pool";

// send the transaction
Portal
    .initiatePool(
        0,
        0,
        your_address,
        pool_name,
        "0x",
        [true, false, false])
    .send({
        value: String(32e18),
    });

pool_ID = Portal.generateId(pool_name, 5);

Complex Initiation

The below transaction creates a Public Staking Pool with a 5% maintenance fee, and ERC20InterfacePermitUpgradable interface, which also has a bound Liquidity Pool:

const getBytes = (key) => {
  return Web3.utils.toHex(key);
};

const intToBytes32 = (x) => {
  return ethers.utils.hexZeroPad(ethers.utils.hexlify(x), 32);
};


// EDIT HERE
// Pool
const your_address="0xabcdf....abcdf";
const pool_name= "IceBear's Pool";
const pool_fee = 5 // 5%
// interfaces = ["ERC20", "ERC20Permit"];
const interface_version = "ERC20Permit";
const interface_name = "IceBear Staked Ether";
const interface_symbol= "IETH"
// Config
const is_private_pool = false;
const use_interface = true;
const use_liquidity_pool = true;
// EDIT HERE



// DO NOT TOUCH HERE
const name_bytes = getBytes(interface_name ).substr(2);
const symbol_bytes = getBytes(interface_symbol).substr(2);
const interface_data =
  intToBytes32(nameBytes.length / 2) + nameBytes + symbolBytes;
const interface_id =  await Portal.generateId(interface_version, 31);
const denominator=10 ** 10;
await Portal
    .initiatePool(
    Math.floor((pool_fee * denominator) / 100),
    interface_id,
    deployer.address,
    getBytes(pool_name),
    interfaceData,
    [is_private_pool , use_interface , use_liquidity_pool ],
    {
      from: deployer,
      log: true,
      value: String(32e18),
    },
  );
  
  const pool_ID = Portal.generateId(pool_name, 5);
  console.log("your pool id:", pool_ID);
📗
⛏️Maintainers
🎭Current Interfaces
Private Pools and Whitelisting