> For the complete documentation index, see [llms.txt](https://snowconedao.gitbook.io/snowconedao/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://snowconedao.gitbook.io/snowconedao/build/treasury-extensions/data-source.md).

# Data Source

**Specifications**

A contract can be transformed into a treasury data source by adhering to ISnowconeFundingCycleDataSource3\_1\_1:

```javascript
interface ISnowconeFundingCycleDataSource3_1_1 is IERC165 {
  function payParams(
    SnowconePayParamsData calldata data
  )
    external
    view
    returns (
      uint256 weight,
      string memory memo,
      SnowconePayDelegateAllocation3_1_1[] memory delegateAllocations
    );

  function redeemParams(
    SnowconeRedeemParamsData calldata data
  )
    external
    view
    returns (
      uint256 reclaimAmount,
      string memory memo,
      SnowconeRedemptionDelegateAllocation3_1_1[] memory delegateAllocations
    );
}

```

Two functions must be implemented, `payParams(...)` and `redeemParams(...)`. Either one can be left empty if the intent is to only extend the treasury's pay functionality or redeem functionality.

**Pay**

When extending the pay functionality with a data source, the protocol will pass a SnowconePayParamsData to the `payParams(...)` function:

```javascript
struct SnowconePayParamsData {
  ISnowconePaymentTerminal terminal;
  address payer;
  SnowconeTokenAmount amount;
  uint256 projectId;
  uint256 currentFundingCycleConfiguration;
  address beneficiary;
  uint256 weight;
  uint256 reservedRate;
  string memo;
  bytes metadata;
}

struct SnowconeTokenAmount {
  address token;
  uint256 value;
  uint256 decimals;
  uint256 currency;
}

```

Using these params, the data source's `payParams(...)` function is responsible for either reverting or returning a few bits of information:

`weight` is a fixed point number with 18 decimals that the protocol can use to base arbitrary calculations on. For example, payment terminals based on the SnowconePayoutRedemptionPaymentTerminal3\_1\_1, such as SnowconeETHPaymentTerminal3\_1\_1's and SnowconeERC20PaymentTerminal3\_1\_1's, use the weight to determine how many project tokens to mint when a project receives a payment (see the calculation). By default, the protocol will use the weight of the project's current funding cycle, which is provided to the data source function in SnowconePayParamsData.weight. Increasing the weight will mint more tokens and decreasing the weight will mint fewer tokens, both as a function of the amount paid. Return the SnowconePayParamsData.weight value if no altered functionality is desired.

`memo` is a string emitted within the Pay event and sent along to any delegate that this function also returns. By default, the protocol will use the memo directly passed in by the payer, which is provided to this data source function in SnowconePayParamsData.memo. Return the SnowconePayParamsData.memo value if no altered functionality is desired.

`delegateAllocations` is an array containing delegates, amounts to send them, and metadata to pass to them.

`delegateAllocations.delegate` is the address of a contract that adheres to ISnowconePayDelegate3\_1\_1 whose `didPay(...)` function will be called once the protocol finishes its standard payment routine. Check out how to build a pay delegate for more details. If the same contract is being used as the data source and the pay delegate, return `address(this)`. Return the zero address if no additional functionality is desired.

`delegateAllocations.amount` is the amount of tokens to send to the delegate.

`delegateAllocations.metadata` is the metadata to pass to the delegate.

The `payParams(...)` function can also revert if it's presented with any conditions it does not want to accept payments under.

The `payParams(...)` function has implicit permission to SnowconeController3\_1.mintTokensOf(...) for the project.

**Redeem**

When extending redeem functionality with a data source, the protocol will pass a SnowconeRedeemParamsData to the `redeemParams(...)` function:

```javascript
struct SnowconeRedeemParamsData {
  ISnowconePaymentTerminal terminal;
  address holder;
  uint256 projectId;
  uint256 currentFundingCycleConfiguration;
  uint256 tokenCount;
  uint256 totalSupply;
  uint256 overflow;
  SnowconeTokenAmount reclaimAmount;
  bool useTotalOverflow;
  uint256 redemptionRate;
  uint256 ballotRedemptionRate;
  string memo;
  bytes metadata;
}

```

Using these params, the data source's `redeemParams(...)` function is responsible for either reverting or returning a few bits of information:

`reclaimAmount` is the amount of tokens in the treasury that the terminal should send out to the redemption beneficiary as a result of burning the amount of project tokens tokens specified in SnowconeRedeemParamsData.tokenCount, as a fixed point number with the same amount of decimals as SnowconeRedeemParamsData.decimals. By default, the protocol will use a reclaim amount determined by the standard protocol bonding curve based on the redemption rate the project has configured into its current funding cycle, which is provided to the data source function in SnowconeRedeemParamsData.reclaimAmount. Return the SnowconeRedeemParamsData.reclaimAmount value if no altered functionality is desired.

`memo` is a string emitted within the RedeemTokens event and sent along to any delegate that this function also returns. By default, the protocol will use the memo passed in directly by the redeemer, which is provided to this data source function in SnowconeRedeemParamsData.memo. Return the SnowconeRedeemParamsData.memo value if no altered functionality is desired.

`delegateAllocations` is an array containing delegates, amounts to send them, and metadata to pass to them.

`delegateAllocations.delegate` is the address of a contract that adheres to ISnowconeRedemptionDelegate3\_1\_1 whose `didRedeem(...)` function will be called once the protocol finishes its standard redemption routine (but before the reclaimed amount is sent to the beneficiary). Check out how to build a redemption delegate for more details. If the same contract is being used as the data source and the redemption delegate, return `address(this)`. Return the zero address if no additional functionality is desired.

`delegateAllocations.amount` is the amount of tokens to send to the delegate.

`delegateAllocations.metadata` is the metadata to pass to the delegate.

The `redeemParams(...)` function can also revert if it's presented with any conditions it does not want to accept redemptions under.

**Attaching**

New data source contracts should be deployed independently. Once deployed, its address can be configured into a project's funding cycle metadata to take effect while that funding cycle is active. Additionally, the metadata's `useDataSourceForPay` and/or `useDataSourceForRedeem` should be set to true if the respective data source hook should be referenced by the protocol.

**Examples**

```javascript
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@snowcone-protocol/contracts-v2/contracts/interfaces/ISnowconeFundingCycleDataSource.sol';

contract AllowlistDataSource is ISnowconeFundingCycleDataSource {
  error NOT_ALLOWED();

  mapping(address => bool) allowed;

  function payParams(SnowconePayParamsData calldata _data)
    external
    view
    override
    returns (
      uint256 weight,
      string memory memo,
      ISnowconePayDelegate delegate
    )
  {
    if (!allowed[_data.payer]) revert NOT_ALLOWED();

    // Forward the received weight and memo, and use no delegate.
    return (_data.weight, _data.memo, ISnowconePayDelegate(address(0)));
  }

  // This is unused but needs to be included to fulfill ISnowconeFundingCycleDataSource.
  function redeemParams(SnowconeRedeemParamsData calldata _data)
    external
    pure
    override
    returns (
      uint256 reclaimAmount,
      string memory memo,
      ISnowconeRedemptionDelegate delegate
    )
  {
    // Return the default values.
    return (_data.reclaimAmount.value, _data.memo, ISnowconeRedemptionDelegate(address(0)));
  }
}

```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://snowconedao.gitbook.io/snowconedao/build/treasury-extensions/data-source.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
