> For the complete documentation index, see [llms.txt](https://synbo-labs.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://synbo-labs.gitbook.io/docs/contract-docs/distribution.md).

# Distribution

The Distribution contract provides a comprehensive process for project owners to create and manage distributions...

The `Distribution` contract provides a comprehensive process for project owners to create and manage distributions, while also offering interfaces for users to participate in distributions and claim earnings.

### Contract Functions

The `Distribution` contract, as an extension of the Target contract, provides functionalities including creating distributions, user participation in distributions, cancelling distributions, liquidating distributions, users claiming dividends and distribution tokens. Distribution is a method for project owners to raise funds and allocate tokens through smart contracts.

### Contract Structure

The `Distribution` contract inherits from the `Target` contract and utilizes the `SafeMath library` to ensure the security of numerical operations.

### Important Variables

* **`distributionIndex`**`:` Index ID for distributions, starting from 1.
* **`distributions`**`:` Mapping storing details of each distribution.
* **`distribution2Owner`**`:` Records the owner of each distribution.
* **`distribution2Funding`**`:` Records the funding amount for each distribution.
* **`distribution2Shares`**`:` Records the number of shares for each distribution.
* **`distribution2TargetId`**`:` Associates distribution IDs with target IDs.
* **`userDistributions`**`:` Records the list of distributions in which users participate.
* **`user2disPending`**`:` Records the amount of tokens pending for users in distributions.
* **`user2disHarvest`**`:` Records the amount of tokens harvested by users.
* **`dis2EndTime`**`:` Records the end time of distributions.

### The Functions:

1. **Events**
   * **`NewDistributionCreated`**`:` Triggered when a new distribution is created.
   * **`NewJoin`**`:` Triggered when a user participates in a distribution.
   * **`HarvestDividends`**`:` Triggered when a user harvests dividends.
   * **`HarvestDisToken`**`:` Triggered when a user harvests distribution tokens.
2. **Distribution Management**
   * **`createDistribution`**`:` Creates a new distribution, subject to specific conditions such as project status and user permissions.
   * **`cancelDistribution`**`:` Allows the owner to cancel a distribution, transitioning its status to `310`.
   * **`ownerLiquidation`**`:` Allows the owner to liquidate a distribution after it fails, transitioning its status to `330`.
3. **User Participation**
   * **`userJoin`**`:` Allows users to participate in a distribution using native tokens, recording the participation amount and token quantity.
4. **Claiming Dividends and Tokens**
   * **`pendingDividends`**`:` Checks the dividends available for a user to claim.
   * **`harvestDividends`**`:` Allows a user to claim their dividends.
   * **`pendingDisToken`**`:` Checks the distribution tokens available for a user to claim.
   * **`harvestDisToken`**`:` Allows a user to claim their distribution tokens.
5. **Project Payment**
   * **`payToken`**`:` Allows the project owner to make a payment, transferring assets to the contract and updating the status to `250`.
6. **Whitelist Management**
   * **`setCheckWhitelist`**`:` Allows the distribution owner to set whitelist addresses.
7. **Query Functions**
   * **`getUserDisIds`**`:` Retrieves a list of all distribution IDs in which a user has participated.
   * **`getDis2WhiteList`**`:` Retrieves the whitelist status of a user in a specific distribution.
   * **`getDisPrice`**`:` Calculates the premium for a distribution.

### Logic

* The creator of a distribution must be a Contractor of the project, and the project status needs to be valid.
* Users can participate in a distribution using the `userJoin` function with Native Token, earning corresponding token shares based on distribution rules.
* Distribution owners can cancel a distribution or perform liquidation under certain conditions.
* Users can claim dividends and distribution tokens after a successful distribution.

### Interface

```solidity

pragma solidity >=0.8.12;
pragma experimental ABIEncoderV2;

interface IDistribution {
    /**
    @dev Create a distribution
    @param user            User address
    @param distributionId  Distribution ID
     */
    event NewDistributionCreated(address indexed user, uint256 distributionId);

    /**
    @dev User participation event
    @param user            User address
    @param distributionId  Distribution ID
    @param targetID        Corresponding target ID
    @param amount          Participation amount
     */
    event NewJoin(
        address indexed user,
        uint256 distributionId,
        uint256 targetID,
        uint256 amount
    );

    /**
    @dev User harvest dividends event
    @param user          User address
    @param amount        Amount involved
     */
    event HarvestDividends(address indexed user, uint256 amount);

    struct DistributionStruct {
        uint256 indexer1; // Bytecode 1
        uint256 indexer2; // Bytecode 2
        address payAddr; // Payment address, project party's fund payment address
        address tokenAddr; // Token contract address
    }

    /**
    @dev Get the total number of distributions
     */
    function distributionIndex() external view returns (uint256);

    /**
    @dev Get distribution details by ID
    @param _distributionId    Distribution ID
    @return _disStruct        Distribution structure
     */
    function distributions(
        uint256 _distributionId
    ) external view returns (DistributionStruct memory _disStruct);

    /**
    @dev Get the owner of a distribution by ID
    @param _distributionId    Distribution ID
    @return _owner            Owner address
     */
    function distribution2Owner(uint256 _distributionId) external view returns (address _owner);

    /**
    @dev Get the funding amount of a distribution by ID
    @param _distributionId    Distribution ID
    @return _funding          Funding amount
     */
    function distribution2Funding(uint256 _distributionId) external view returns (uint256 _funding);

    /**
    @dev Create a distribution, only contractors can do this
    @param _indexer1          Indexer code 1
    @param _indexer2          Indexer code 2
    @param _payAddr           Payment address, project party's fund payment address
    @param _tokenAddr         Token contract address
     */
    function createDistribution(
        uint256 _indexer1,
        uint256 _indexer2,
        address _payAddr,
        address _tokenAddr
    ) external;

    /**
    @dev User participates using ETH
    @notice msg.value carries the participation amount
    @param _distributionId   Distribution ID
     */
    function userJoin(uint256 _distributionId) external payable;

    /**
    @dev User views their pending dividends
    @param _user         User address
    @return _amount      Pending dividend amount
     */
    function pendingDividends(
        address _user
    ) external view returns (uint256 _amount);

    /**
    @dev User harvests their dividends
     */
    function harvestDividends() external;

    /**
    @dev Project party makes a payment, transferring all assets
    @param _distributionId       Distribution ID
     */
    function payToken(uint256 _distributionId) external;

    /**
    @dev Get the target ID from distribution data
    @param _data           Data
    @return _targetId      Target ID
     */
    function getTargetIdFromDis(uint256 _data) external pure returns (uint256 _targetId);

    /**
    @dev Check if an address is on the whitelist for a distribution
    @param _user              User address
    @param _distributionId    Distribution ID
    @return _isBool           Status
     */
    function distribution2WhiteList(
        uint256 _user,
        uint256 _distributionId
    ) external view returns (bool _isBool);

    /**
    @dev Get the target ID of a distribution by ID
    @param _distributionId    Distribution ID
    @return _targetId         Target ID
     */
    function distribution2TargetId(
        uint256 _distributionId
    ) external view returns (uint256 _targetId);

    /**
    @dev Get aggregate information of a distribution by ID
    @param _user               User address
    @param _distributionId     Distribution ID
    @return _disStruct         Distribution structure
    @return _owner             Owner address
    @return _funding           Current funding amount
    @return _targetId          Corresponding target ID
    @return _joinAmount        User's participation amount in the current distribution
     */
    function getArgInfo2DisId(
        address _user,
        uint256 _distributionId
    )
        external
        view
        returns (
            DistributionStruct memory _disStruct,
            address _owner,
            uint256 _funding,
            uint256 _targetId,
            uint256 _joinAmount
        );

    /**
    @dev Set whitelist, only the distribution owner can set
    @param _distributionId Distribution ID
    @param _whiteList       List of whitelist addresses
    @param _isBool          Status list
     */
    function setCheckWhitelist(
        uint256 _distributionId,
        address[] memory _whiteList,
        bool[] memory _isBool
    ) external;

    /**
    @dev Get all distributions of a user
    @param _user             User address
    @return _distributions   List of distributions
    @return _length Number   of distributions
     */
    function getUserAllDis(
        address _user
    ) external view returns (DistributionStruct[] memory _distributions, uint256 _length);

    /**
    @dev Get all distribution IDs of a user
    @param _user     User address
    @return _ids     List of distribution IDs
     */
    function getUserDisIds(
        address _user
    ) external view returns (uint256[] memory _ids);

    /**
    @dev Check if an address is on the whitelist for a distribution
    @param _user      User address
    @param _id        Distribution ID
    @return _isBool   Status
     */
    function getDis2WhiteList(address _user, uint256 _id) external view returns (bool _isBool);

    /**
    @dev Cancel a distribution, only the distribution owner can do this
    @param _distributionId      Distribution ID
     */
    function cancelDistribution(uint256 _distributionId) external;
}





```
