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
  • Portal is The Main Gateway to Trustless Staking
  • TYPE
  • Reading variables from Portal
  • Reading Arrays from Portal
  • Reading Relational Data from Portal
  • Thats it!
  1. Ethereum Guides
  2. Operator Handbook

Communicating with Portal

PreviousInitiating an OperatorNextCreating Validators

Last updated 2 years ago

Portal is The Main Gateway to Trustless Staking

Learn more about Portal here, if you want:

Portal utilizes a Modular Architecture build on top of an Isolated Storage.

This is good for us, because we can add any functionality without minding the backward compatibility. It is good for the users because no one can touch their instance of the contract storage.

However, this means, sadly, things are not that direct...

Learn more about it here, if you want:

TYPE

We have already learned a bit about IDs while initiating our Operator.

There are many TYPEs that are supported by Portal. Modules like Withdrawal Contract, Liquidity Pools, Interfaces...

However, as Node Operators, we are only interested in two of them: Operator and Pool.

Representation of an Operator' storage space:

const OPERATOR = {
"CONTROLLER": <address>,
"NAME": <bytes>,
"TYPE": 4 <uint>,
"initiated": <uint>,
"maintainer": <address>,
"totalProposedValidators": <uint>,
"totalActiveValidators": <uint>,
"feeSwitch": <uint>,
"priorFee": <uint>,
"fee": <uint>,
"periodSwitch": <uint>,
"priorPeriod": <uint>,
"validatorPeriod": <uint>,
"wallet": <uint>,
"released": <uint>
};

Representation of a Pool's storage space:

const POOL= {
"CONTROLLER": <address>,
"NAME": <bytes>,
"TYPE": 5 <uint>,
"initiated": <uint>,
"maintainer": <address>,
"surplus": <uint>,
"secured": <uint>,
"allowance": {<OPERATOR>: <uint>},
"proposedValidators": {<OPERATOR>: <uint>},
"activeValidators": {<OPERATOR>: <uint>},
"interfaces": [<address>],
"private": <uint>, // 1 = true
"whitelist": <address>,
"withdrawalCredential": <bytes>,
"withdrawalContract": <address>,
"liquidityPool": <address>,
"liquidityPoolVersion": <uint>,
"feeSwitch": <uint>,
"priorFee": <uint>,
"fee": <uint>,
"wallet": <uint>,
"validators": [<bytes>]
};

surplus, allowance and withdrawalContract are super important for us!

Reading variables from Portal

First, some helpers:

const getBytes32 = (key) => {
  return ethers.utils.formatBytes32String(key);
};

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

Reading UINT variable:

await PORTAL.readUintForId(
  id,
  getBytes32("surplus")
);

Reading ADDRESS variable:

await PORTAL.readAddressForId(
  id,
  getBytes32("CONTROLLER")
);

Reading BYTES variable:

await PORTAL.readBytesForId(
  id,
  getBytes32("withdrawalCredential")
);

Reading Arrays from Portal

Reading UINT array:

await PORTAL.readUintArrayForId(
  id,
  getBytes32("something"),
  index
);

Reading ADDRESS array:

await PORTAL.readBytesArrayForId(
  id,
  getBytes32("interfaces"),
  index
);

Reading BYTES array:

await PORTAL.readAddressArrayForId(
  id,
  getBytes32("validators"),
  index
);

Reading Relational Data from Portal

Reading UINT data:

await PORTAL.readUintForId(
  poolId,
  await PORTAL.getKey(operatorId, getBytes32("allowance"))
);

Reading ADDRESS data:

await PORTAL.readAddressForId(
  poolId,
  await PORTAL.getKey(operatorId, getBytes32("something"))
);

Reading BYTES data:

await PORTAL.readBytesForId(
  poolId,
  await PORTAL.getKey(operatorId, getBytes32("something"))
);

Thats it!

📕
🌀Portal
🔐Isolated Storage