# Referrals

I'll create comprehensive documentation for the Referrals system within the Common Protocol. Using the provided smart contract code, I'll follow the documentation standard you shared.

## Common Protocol: Referral System Documentation

### Introduction

The Referral System is a core component of the Common Protocol that enables communities to grow through incentive-aligned user acquisition. This system allows communities to reward users who bring in new members by providing them with a percentage of fees generated when new users participate in community activities.

**Core Concepts**:

* **Referral Tracking**: Permanent association between referrers and new users at the namespace level
* **Fee Distribution**: Automatic sharing of fees between the protocol and referrers
* **Role-based Access Control**: Clearly defined permissions for managing the referral system
* **Hook Architecture**: Integration with contest rewards via hooks to distribute referral fees

### Deployments

*Last Updated: April 23, 2025*

#### Base Network

| Contract Name      | Address                                    |
| ------------------ | ------------------------------------------ |
| ReferralFeeManager | 0x9d3be262bed6f3a0aab4e97c0232071ef730632f |
| ReferralClaimHook  | 0x5fd4a4e28ef1eab1f74046ac15039ad05064345b |
| ReferralActionHook | 0x4b6ecd9ecd73c38b5ba56f07c70ca122b9bdefbc |

### Events

#### Event Signatures Table

| Event Name                    | Contract Name          | Event Signature (topic0)                                             |
| ----------------------------- | ---------------------- | -------------------------------------------------------------------- |
| ReferralFeeManagerUpdated     | ReferralClaimHook      | `0x9d85e94583b70b4c8eaa1380c1ab273059ef5262210c586dd9e3c971983af4e1` |
| OwnershipTransferred          | ReferralClaimHook      | `0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0` |
| ContentRewardClaimed          | ReferralClaimHook      | `0xe23ea816df6f7ed451d5e8be6dbca9bc76201d536ae4efd243376738328af7c0` |
| ReferralSet                   | ReferralFeeManager     | `0x6a82ba25a343bab95b3518662f6499be99c97b63d87bafa38885aa3216fd567d` |
| FeeSplitUpdated               | ReferralFeeManager     | `0x5369a034ba5317502afd913e9ec49a3091a529f712e3d3b3e5c6f775db3b7d6b` |
| ProtocolFeeDestinationUpdated | ReferralFeeManager     | `0xac4a732467bcd6f0a4628e9da8af90dfced86d76ca1dd0e124f494e5b88cb094` |
| FeesDistributed               | ReferralFeeManager     | `0xdeb4e2bedfdae1d261c2e1c3ce95284a9dac87d6e6f819aca53ebf88a6c67bb6` |
| FeeDistributorAdded           | ReferralFeeManager     | `0x70e0a2c1e15d36115ea07302475e5d10e5fefe2033bef9c0eaacf35c354d6e6e` |
| FeeDistributorRemoved         | ReferralFeeManager     | `0x02bc21baa5cb9bea5d80f12506ec4ea06e1e8ecb2a2cad32037067be5c434a84` |
| OwnershipTransferred          | ReferralFeeManager     | `0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0` |
| BeneficiaryAdded              | FeeManager (inherited) | `0x938b2a24c98e4435ab4431d93e18a0ea23ca31bb21d914ab58d02f95a63b7a21` |
| BeneficiaryRemoved            | FeeManager (inherited) | `0x386ca106f85a29171639b9914037e4b87900841c9193d3ce53b490a71ac27278` |
| BeneficiaryUpdated            | FeeManager (inherited) | `0x7cfbcfebf6e794c4325d7c37e709ef0fe9f3eb464b52157b5ad7012a42aae631` |
| ETH\_FeeDistributed           | FeeManager (inherited) | `0xe64558d7aa0e8eae8b46cf4411eddbb6e8a66a555aaf7239549e887536d0cbb6` |
| ERC20\_FeeDistributed         | FeeManager (inherited) | `0xe8f9da4ef4ab6fa89f6a1957a21baef328c556a8e99b7e3966b3848c6aad42ba` |

#### Events By Contract

**ReferralClaimHook**

**ReferralFeeManagerUpdated**

* **Explanation**: Emitted when the ReferralFeeManager address is updated
* **Parameters**:

```solidity
event ReferralFeeManagerUpdated(address indexed oldManager, address indexed newManager);
```

* **Called By**: `updateReferralFeeManager`

**OwnershipTransferred**

* **Explanation**: Emitted when ownership of the contract is transferred
* **Parameters**:

```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
```

* **Called By**: `transferOwnership`

**ContentRewardClaimed**

* **Explanation**: Emitted when a content reward is claimed through the hook
* **Parameters**:

```solidity
event ContentRewardClaimed(address indexed winner, uint256 indexed position);
```

* **Called By**: `preClaimContentReward`

**Fee Distribution Mechanics**:

* The hook intercepts contest reward claims through the `preClaimContentReward` function
* When the first position winner (id = 0) claims their reward, the hook triggers fee distribution
* The hook identifies the namespace and contest token from the calling contest contract
* It then calls the ReferralFeeManager to distribute any accumulated fees for that namespace and token
* This ensures that referral fees are processed at the moment of reward distribution, creating a seamless user experience

**ReferralFeeManager**

**ReferralSet**

* **Explanation**: Emitted when a referral relationship is established for a namespace
* **Parameters**:

```solidity
event ReferralSet(address indexed namespace, address indexed referral);
```

* **Called By**: `setReferral`

**FeeSplitUpdated**

* **Explanation**: Emitted when the fee split percentage is updated
* **Parameters**:

```solidity
event FeeSplitUpdated(uint256 newSplitPercentage);
```

* **Called By**: `setFeeSplit`

**ProtocolFeeDestinationUpdated**

* **Explanation**: Emitted when the protocol fee destination address is updated
* **Parameters**:

```solidity
event ProtocolFeeDestinationUpdated(address newDestination);
```

* **Called By**: `setProtocolFeeDestination`

**FeesDistributed**

* **Explanation**: Emitted when fees are distributed through the manager
* **Parameters**:

```solidity
event FeesDistributed(address indexed namespace, address indexed token, uint256 amount, address recipient, uint256 recipientAmount);
```

* **Called By**: `distributeFees`

**FeeDistributorAdded**

* **Explanation**: Emitted when a new fee distributor role is granted
* **Parameters**:

```solidity
event FeeDistributorAdded(address indexed newDistributor);
```

* **Called By**: `addFeeDistributor`

**FeeDistributorRemoved**

* **Explanation**: Emitted when a fee distributor role is revoked
* **Parameters**:

```solidity
event FeeDistributorRemoved(address indexed removedDistributor);
```

* **Called By**: `removeFeeDistributor`

**OwnershipTransferred**

* **Explanation**: Emitted when ownership of the contract is transferred
* **Parameters**:

```solidity
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
```

* **Called By**: `setOwner`

Thank you for pointing out these omissions. The updated table now includes all events from both the ReferralClaimHook and ReferralFeeManager contracts, as well as the events inherited from the FeeManager contract.

### Contract Details/Architecture

#### ReferralFeeManager

**Purpose**: Manages the distribution of fees between referrers and the protocol, tracking referral relationships at the namespace level. This contract serves as the central registry for all referral relationships and handles fee splits between referrers and the protocol.

**Key Functions**:

* Set and manage referral relationships between users and namespaces
* Configure the fee split percentages between referrers and the protocol
* Distribute accumulated fees to beneficiaries based on their assigned weights
* Manage role-based access control for different system actions

**Access Control Structure**:

* `NAMESPACEFACTORYROLE`: Allowed to set referral relationships for namespaces
* `FEEDISTRIBUTORROLE`: Allowed to trigger fee distribution
* `OWNER_ROLE`: Administrative role with permissions to update fee percentages and destinations

**State Variables**:

* `namespaceToReferral`: Mapping that ties each namespace to its referrer
* `feeSplitPercentage`: The percentage of fees allocated to referrers (in basis points)
* `protocolFeeDestination`: Address that receives the protocol's share of fees

**Rules**:

* Only addresses with the `NAMESPACEFACTORYROLE` can set referral relationships
* Only addresses with the `FEEDISTRIBUTORROLE` can distribute fees
* Only addresses with the `OWNER_ROLE` can update protocol fee destinations and fee splits
* Fee split percentages must be valid (between 0-100%)
* Each namespace can have only one referrer, once set it cannot be changed
* The contract inherits from AccessControl to manage role-based permissions

**Fee Distribution Logic**:

* When fees are received, they are split between the referrer and protocol based on `feeSplitPercentage`
* If a namespace has a referrer, that referrer receives their share of fees
* If no referrer exists, the entire fee goes to the protocol fee destination
* Distribution supports both native currency (ETH) and ERC20 tokens

**Constructor Parameters**:

The constructor sets up the initial state of the contract, grants appropriate roles, and validates that all parameters meet the required constraints.

| Parameter                     | Description                                                                 | Requirements              |
| ----------------------------- | --------------------------------------------------------------------------- | ------------------------- |
| namespaceFactory              | Address of the namespace factory that will have permission to set referrals | Cannot be zero address    |
| owner                         | Address of the initial contract owner                                       | Cannot be zero address    |
| initialFeeSplit               | Initial percentage of fees allocated to referrers (0-100)                   | Must be between 0 and 100 |
| initialProtocolFeeDestination | Initial address to receive protocol's share of fees                         | Cannot be zero address    |

**Function Table**:

| Function Name             | Input Parameters                      | Visibility         | Events It Triggers            | Description                                                                        |
| ------------------------- | ------------------------------------- | ------------------ | ----------------------------- | ---------------------------------------------------------------------------------- |
| setReferral               | `address namespace, address referral` | External           | ReferralSet                   | Associates a referrer with a namespace, creating a permanent referral relationship |
| setFeeSplit               | `uint256 percentage`                  | External           | FeeSplitUpdated               | Sets the percentage of fees that go to referrers vs protocol                       |
| setProtocolFeeDestination | `address destination`                 | External           | ProtocolFeeDestinationUpdated | Updates the address that receives protocol fees                                    |
| addFeeDistributor         | `address distributor`                 | External           | FeeDistributorAdded           | Grants an address permission to distribute fees                                    |
| removeFeeDistributor      | `address distributor`                 | External           | FeeDistributorRemoved         | Revokes fee distribution permission from an address                                |
| setOwner                  | `address newOwner`                    | External           | OwnershipTransferred          | Transfers ownership of the contract                                                |
| distributeFees            | `address token, address namespace`    | External           | FeesDistributed               | Distributes accumulated fees to referrers and protocol                             |
| namespaceToReferral       | `address namespace`                   | External           | -                             | View function to get the referrer for a namespace                                  |
| feeSplitPercentage        | -                                     | External           | -                             | View function to get the current fee split percentage                              |
| protocolFeeDestination    | -                                     | External           | -                             | View function to get the current protocol fee destination                          |
| hasRole                   | `bytes32 role, address account`       | External           | -                             | Checks if an account has a specific role                                           |
| receive                   | -                                     | External (payable) | -                             | Fallback function that allows the contract to receive ETH transactions             |

#### ReferralClaimHook

**Purpose**: Integrates with the Contest Governor to allow fee distribution to referrers when content rewards are claimed. This hook captures a portion of contest rewards and directs them to the appropriate referrers.

**Key Functions**:

* Hook into contest reward distribution to capture referral fees
* Pass referral fees to the ReferralFeeManager for distribution
* Integrate with the Contest Governor's claim reward flow

**Architecture**:

* Implements the `IContestGovernorClaimHook` interface
* Maintains a reference to the ReferralFeeManager contract
* Uses an ownership model for administrative functions

**Integration Points**:

* Pre and post claim hooks for content rewards
* Pre and post claim hooks for voter rewards
* Direct interaction with ReferralFeeManager for fee distribution

**Rules**:

* Only works with content from namespaces that have referrals set
* Cannot modify the claim process, only observe and react to it
* Maintains ownership controls for updating the ReferralFeeManager address
* Does not interfere with the normal operation of reward distribution

**Constructor Parameters**:

| Parameter            | Description                                | Requirements           |
| -------------------- | ------------------------------------------ | ---------------------- |
| \_referralFeeManager | Address of the ReferralFeeManager contract | Cannot be zero address |
| init\_owner          | Initial owner of the contract              | Cannot be zero address |

The constructor initializes the contract with references to the ReferralFeeManager and sets up the ownership structure.

**Function Table**:

| Function Name            | Input Parameters                     | Visibility | Events It Triggers        | Description                                                      |
| ------------------------ | ------------------------------------ | ---------- | ------------------------- | ---------------------------------------------------------------- |
| preClaimContentReward    | `address winner, uint256 id`         | External   | -                         | Called before contest rewards are claimed to prepare fee capture |
| updateReferralFeeManager | `address manager`                    | External   | ReferralFeeManagerUpdated | Updates the reference to the ReferralFeeManager contract         |
| transferOwnership        | `address newOwner`                   | External   | OwnershipTransferred      | Transfers ownership of the contract                              |
| postClaimContentReward   | `address winner, uint256 id`         | External   | ContentRewardClaimed      | Called after claim to process referral fees                      |
| preClaimVoterReward      | `address voter, uint256 votingPower` | External   | -                         | Called before voter rewards are claimed                          |
| postClaimVoterReward     | `address voter, uint256 votingPower` | External   | -                         | Called after voter rewards are claimed                           |

#### ReferralActionHook

**Purpose**: Integrates with bonding curve transactions to capture and distribute fees to referrers. This hook monitors token buy/sell actions to extract fees for referrers.

**Key Functions**:

* Capture fees from token buy/sell transactions on bonding curves
* Pass fees to ReferralFeeManager for distribution to referrers
* Integrate with the bonding curve ecosystem

**Architecture**:

* Implements the `ICurveActionHook` interface
* Maintains references to relevant contracts (bonding curve, token manager, referral manager)
* Uses an ownership model for administrative functions

**Integration Points**:

* Post-buy hooks for token purchases
* Post-sell hooks for token sales
* Direct interaction with ReferralFeeManager for fee distribution

**Token Flow**:

* When users buy/sell tokens through the bonding curve, fees are captured
* The hook determines if the namespace has a referrer
* If a referrer exists, appropriate fees are directed to the ReferralFeeManager
* This creates a seamless integration between token trading and referral rewards

**Rules**:

* Only the bonding curve contract can trigger hooks
* Only works with namespaces that have referrals set
* Cannot modify the buy/sell process, only observe and react to it
* Maintains ownership controls for updating contract references

**Function Table**:

| Function Name          | Input Parameters                                                             | Visibility | Events It Triggers | Description                                            |
| ---------------------- | ---------------------------------------------------------------------------- | ---------- | ------------------ | ------------------------------------------------------ |
| postBuyHook            | `address buyer, address namespace, uint256 id, uint256 amount, uint256 fee`  | External   | -                  | Called after a token purchase to process referral fees |
| postSellHook           | `address seller, address namespace, uint256 id, uint256 amount, uint256 fee` | External   | -                  | Called after a token sale to process referral fees     |
| setBondingCurveAddress | `address curve`                                                              | External   | -                  | Updates the reference to the bonding curve contract    |
| setTokenManager        | `address manager`                                                            | External   | -                  | Updates the reference to the token manager contract    |
| setReferralManager     | `address manager`                                                            | External   | -                  | Updates the reference to the referral manager contract |
| newOwner               | `address owner`                                                              | External   | -                  | Updates the owner of the contract                      |

### User Flows

#### Setting Up a Referral Relationship

**Flow Description**: This process establishes a permanent referral relationship between a referrer and a namespace. When the namespace generates fees, a portion will be directed to the referrer.

**Flow Steps**:

1. User A creates a new namespace through the NamespaceFactory
2. During namespace creation, User A provides the address of the referrer (User B)
3. The NamespaceFactory calls the ReferralFeeManager's `setReferral` function
4. ReferralFeeManager records the referral relationship by mapping the namespace to the referrer
5. All future fee-generating activities in this namespace will now allocate a portion to User B

**Flow Chart**:

```
User A                 NamespaceFactory               ReferralFeeManager
  │                           │                               │
  │   Create Namespace        │                               │
  │   with Referrer B         │                               │
  │───────────────────────-──>│                               │
  │                           │                               │
  │                           │      setReferral              │
  │                           │      (namespace, B)           │
  │                           │──────────────────────────────>| Store:
  │                           │                               │ namespaceToReferral[namespace] = B
  │                           │                               │ 
  │                           │                               │
  │      Namespace Created    │                               │
  │<───────────────────────-──│                               │
  │                           │                               │
```

#### Fee Distribution Flow

**Flow Description**: When fees are collected from various activities (contests, token trades, etc.), they are distributed between the protocol fee destination and referrers according to the configured split.

**Flow Steps**:

1. A fee-generating action occurs (e.g., token purchase, contest reward claim)
2. The appropriate hook captures the fee and sends it to the ReferralFeeManager
3. A distributor (any address with FEEDISTRIBUTORROLE) calls the `distributeFees` function
4. ReferralFeeManager checks if the namespace has a referrer
5. If a referrer exists, fees are split according to the configured percentage
6. The referrer receives their portion, and the protocol fee destination receives the remainder

**Flow Chart**:

```
User                    Hook Contract              ReferralFeeManager          Beneficiaries  
  │                           │                           │                         │
  │   Fee-generating action   │                           │                         │
  │─────────────────────────->│                           │                         │
  │                           │                           │                         │
  │                           │    Send fee to Manager    │                         │
  │                           │──────────────────────────>│                         │
  │                           │                           │                         │
  │                           │                           │  ┌───────────────────┐  │
  │                           │                           │  │ 1. Check referral │  │
  │                           │                           │  │ 2. Calculate split│  │
  │                           │                           │  └───────────────────┘  │
  │                           │                           │                         │
  │                           │                           │     Distribute fees     │
  │                           │                           │────────────────────────>│
  │                           │                           │                         │
  │      Action completed     │                           │                         │
  │<─────────────────────────-│                           │                         │
  │                           │                           │                         │
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.common.xyz/commonwealth/protocol/referral_docs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
