📃
Graph Codex
  • Welcome to The Graph Codex
  • Getting Started
    • Websites
    • Resources
  • Meetings and Events
    • Core Developers Calls
    • Community Talks
    • Indexer Office Hours
    • NFT Community Calls
  • Workshops
    • Subgraph Development
      • Resources
        • Hackathon Workshops
          • Blockchain Development - Querying with Open APIs Course
          • Building a Custom NFT API with Filtering, Sorting, Full Text Search, and Relationships
          • Building a custom NFT API with The Graph
          • Building a Subgraph on Celo @ The Cross Chain Salon
          • Building a Subgraph with Subgraph Studio
          • Building an NFT API and Subgraph on NEAR with The Graph
          • Building an NFT API with the Graph - Nader Dabit
          • Building an NFT Subgraph - Kuneco April 2021
          • Building and Deploying Subgraphs on TheGraphProtocol
          • Building API's on Ethereum, with Nader Dabit
          • Building Apps on the Decentralized Web with Nader Dabit
          • Building Decentralised GraphQL APIs with The Graph
          • Building on Ethereum with GraphQL, The Graph, and Next.js
          • Building Rich APIs on top of Ethereum with The Graph
          • Building Subgraphs on The Graph - MarketMake
          • Building Subgraphs on The Graph
          • Building Subgraphs with The Graph
          • Defining the Web3 Stack - Nader Dabit - (Next.js Conf 2021)
          • How to build a dApp – Nader Dabit
          • How to Build a Full Stack NFT Marketplace on Ethereum with Polygon and Next.js
          • How to Build an NFT API with The Graph
          • Indexing Smart Contracts with OpenZeppelin Subgraphs & The Graph
          • NFT Dev Talk, GenerativeMasks, and Building NFT APIs with OpenZeppelin, GraphQL, and The Graph
          • Query Ethereum with GraphQL with The Graph
          • The Complete Guide to Full Stack Web3 Development
          • Web3 with Nader Dabit
          • Workshop on How to Build Subgraphs
        • Repositories
      • Developer Highlights
      • Developer Guides
      • Subgraph Testing (Matchstick)
    • Protocol Workshops
  • Ecosystem Updates
    • This Month in Indexing
    • This Month in Curation
    • Council Meeting Notes
    • Governance
      • Governance Resources
      • Graph Improvement Proposals (GIPs)
        • 0000-template
        • 0001-gip-process
        • 0002-gip-withdraw-indexer-rewards
        • 0003-gip-rewards-no-signal
        • 0004-gip-withdraw-indexer-rewards-thawing
        • 0005-gas-costing
        • 0006-gip-withdraw-helper
        • 0007-separate-slashing-percentages
        • 0008-subgraph-api-versioning-and-feature-support
        • 0009-arbitration-charter
        • 0010-rewards-snapshot-empty-poi-fix
        • 0011-stake-to-init-fix
        • 0012-cache-contract-addresses
        • 0013-reduce-curation-tax
        • 0014-batch-gns-transactions
        • 0015-allow-unstake-passing-larger-amount-available
        • 0016-revert-precision-assign-delegation-share
        • 0017-allow-batching-calls-staking-contract
        • 0018-subgraph-ownership-transfer
        • 0019-save-gas-initializing-subgraph-deployment
        • 0020-unattestable-indexer-responses
        • 0023-subgraph-ownership-transfer-nft
        • 0024-query-versioning
        • 0025-principal-protected-bonding-curves
        • 0026-decaying-curation-tax
      • Graph Request for Comments (GRCs)
        • 0001-data-edge
  • Repositories and Documentation
    • Official Repositories
    • Official Documentation
      • About
        • Introduction
        • Network Overview
      • Developer
        • Quick Start
        • Define a Subgraph
        • Create a Subgraph
        • Publish a Subgraph to the Decentralized Network
        • Query The Graph
        • Querying from an Application
        • Querying Best Practices
        • Distributed Systems
        • AssemblyScript API
        • AssemblyScript Migration Guide
        • GraphQL API
        • Unit Testing Framework
        • Deprecating a Subgraph
        • Developer FAQs
      • Indexer
      • Delegator
      • Curator
      • The Graph Explorer
      • Subgraph Studio
        • How to use the Subgraph Studio
        • Deploy a Subgraph to the Subgraph Studio
        • Billing on the Subgraph Studio
        • Managing your API Keys
        • Subgraph Studio FAQs
        • Multisig Users
      • Hosted Service
        • What is Hosted Service?
        • Deploy a Subgraph to the Hosted Service
        • Migrating an Existing Subgraph to The Graph Network
      • Supported Networks
        • NEAR
Powered by GitBook
On this page
  • Abstract
  • Motivation
  • Detailed Specification
  • Features
  • Requirements
  • Exceptions
  • Handled Exceptions
  • Assumptions
  • Backwards Compatibility
  • Validation
  • Audits
  • Testnet
  • Copyright Waiver

Was this helpful?

Edit on GitHub
  1. Ecosystem Updates
  2. Governance
  3. Graph Improvement Proposals (GIPs)

0006-gip-withdraw-helper

Previous0005-gas-costingNext0007-separate-slashing-percentages

Last updated 3 years ago

Was this helpful?

Abstract

Consumers in the Graph Network set up state channels for sending query fees to Indexers using Vector. is an ultra-simple, flexible state channel protocol implementation. This proposal introduces a contract required to encode custom logic in the process of withdrawing query fees from Vector state channels. The GRTWithdrawHelper contract receives query fees from a Vector state channel, then it forwards them to the Staking contract where they are distributed according to the protocol economics.

Motivation

Vector state channels are contracts that hold funds used as collateral for consumer-to-indexer payments. When an Indexer closes an allocation, both parties sign a withdrawal commitment to transfer the query fees accumulated for the allocation back to the network. Vector, by default, supports plain transfers from the channel to any destination defined in the withdrawal commitment. In the case of the Graph Network, all funds should be collected by calling the collect() function in the Staking contract. For the purpose of calling custom logic when transferring from channels, Vector supports using a WithdrawHelper contract. In this proposal, we describe the implementation of such a contract for connecting a Vector withdrawal transfer to The Graph smart contracts.

Detailed Specification

We created a contract called GRTWithdrawHelper that extends the base WithdrawHelper provided by the Vector framework. This contract has a function execute(WithdrawData _wd, uint256 _actualAmount) external that is called in the same transaction when the indexer withdraw funds from the channel. The execute function evaluates the validity of the WithdrawData struct, and then approve and transfer the received funds to the Staking contract by calling collect().

Transaction Flow

Channel->GRTWithdrawHelper: transfer(_actualAmount)
Channel->GRTWithdrawHelper: execute(WithdrawData _wd, uint256 _actualAmount)
GRTWithdrawHelper->Staking: approve(_actualAmount)
GRTWithdrawHelper->Staking: collect(_actualAmount, allocationID)
Staking->GRTWithdrawHelper: transferFrom(_actualAmount)

Features

  • The GRTWithdrawHelper is deployed with the token address that will be used for transfers, in our case it is the GRT token address. It can't be changed at later stage but this can easily be solved deploying a new contract if needed.

  • The contract expects to have available tokens in balance when execute(WithdrawData calldata wd, uint256 actualAmount) is called by the Channel. For that to happen the Channel needs to transfer funds to the GRTWithdrawHelper before execute is called.

  • On execute, the GRTWithdrawHelper will approve the funds to send to the Staking contract and then execute collect() passing the proper allocationID and amount. The Staking contract will then pull the tokens.

  • If the call to collect() fails, the funds are returned to a return address. This is important for Vector accounting of funds.

Requirements

  • Set the GRTWithdrawHelper contract as AssetHolder in the Staking contract. This way we allow the network contracts to accept funds from this contract.

  • The cooperative withdrawal commitments must have the following data (indicated with arrows):

struct WithdrawData {
    address channelAddress;
    address assetId;            // -> GRT token address
    address payable recipient;  // -> GRTWithdrawHelper contract address
    uint256 amount;
    uint256 nonce;
    address callTo;             // -> GRTWithdrawHelper contract address
    bytes callData;             // -> CollectData struct defined below
}
struct CollectData {
    address staking;        // -> Staking contract address
    address allocationID;   // -> AllocationID to send collected funds
    address returnAddress;  // -> Address where to return funds in case of errors
}

The parties must agree and sign the WithdrawalCommitment with that information to achieve proper execution of the withdrawals.

Exceptions

The following conditions will result in reverts of the execution:

  • assetId in WithdrawData not matching the token address configured in the GRTWithdrawHelper.

  • GRTWithdrawHelper not having enough balance to transfer the Staking contract as stated in actualAmount.

  • Setting an invalid staking contract address.

Note: To avoid unexpected conditions in the Vector off-chain logic, it is encouraged that the parties verify the WithdrawData does not revert by doing a call/estimateGas.

Handled Exceptions

These reverts are handled and will make the contract to return the funds to the return address.

  • Doing a withdrawal for a non-existing allocationID as defined in CollectData when calling collect().

Assumptions

  • This contract does not know if a WithdrawalCommitment is correct, it just accepts a transfer and WithdrawData that defines a proper destination.

  • A properly formatted WithdrawData can be crafted to send outside funds to the Staking contract. In that case, the person will get those funds distributed with Curators + Delegators + taxed a protocol percentage. There is no rational economic incentive to do so.

Backwards Compatibility

The contract in this proposal is new and peripheral to the rest of the network contracts. No breaking change is introduced. The Graph Council will need to set the GRTWithdrawHelper as an AssetHolder in the Staking contract.

Validation

Audits

Testnet

The implementation was deployed and tested on Rinkeby testnet. https://rinkeby.etherscan.io/address/0xe5fa88135c992a385aaa1c65a0c1b8ff3fde1fd4

Copyright Waiver

An audit of the changes described in this document was performed by ChainSafe (see ).

Copyright and related rights waived via .

Vector
assets/gip-0006/TheGraph-GRTWithdrawHelper-Audit.pdf
CC0