arrow-left

All pages
gitbookPowered by GitBook
1 of 17

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Event

SNWProjects

Interfaces

Name
Description

ISnowconeProjects

General interface for the methods in this contract that interact with the blockchain's state according to the protocol's rules.

Inheritance

Contract
Description

Constructor

_operatorStore is an ISnowconeOperatorStore contract storing operator assignments.

Events

Name
Data

Properties

Name
Definition

Read

Function
Definition

Write

Function
Definition

Properties

tokenURI

SnowconeOperatable

Includes convenience functionality for checking a message sender's permissions before executing certain transactions.

ERC721Votes

A checkpointable standard definition for non-fungible tokens (NFTs).

Ownable

Includes convenience functionality for specifying an address that owns the contract, with modifiers that only allow access by the owner.

Create

uint256 indexed projectId, address indexed owner, SnowconeProjectMetadata metadata, address caller

SetMetadata

uint256 indexed projectId, SnowconeProjectMetadata metadata, address caller

SetTokenUriResolver

ISnowconeTokenUriResolver indexed resolver, address caller

count

Returns uint256

metadataContentOf

Params: uint256 _projectId, uint256 _domain Returns: string

tokenUriResolver

Returns ISnowconeTokenUriResolver

tokenURI

Params: uint256 _projectId

supportsInterface

Params: uint256 _interfaceId Returns: bool

createFor

Params: address _owner, SnowconeProjectMetadata _metadata Returns: uint256 projectId

setMetadataOf

Traits: requirePermission Params: uint256 _projectId, SnowconeProjectMetadata _metadata

setTokenUriResolver

Traits: onlyOwner Params: ISnowconeTokenUriResolver _newResolver

tokenUriResolver

Contract: SnowconeProjects

Interface: ISnowconeProjects

The contract resolving each project ID to its ERC721 URI.

Definition

/**
  @notice
  The contract resolving each project ID to its ERC721 URI.
*/
ISnowconeTokenUriResolver public override tokenUriResolver;

The resulting view function can be accessed externally by anyone. The resulting function overrides a function definition from the ISnowconeProjects interface.

constructor(ISnowconeOperatorStore _operatorStore)
  ERC721('Snowcone Projects', 'SNOWCONE')
  EIP712('Snowcone Projects', '1')
  SnowconeOperatable(_operatorStore)
{}

metadataContentOf

Contract: SnowconeProjects

Interface: ISnowconeProjects

The metadata for each project, which can be used across several domains.

Definition

Arguments: _projectId is the ID of the project to which the metadata belongs. _domain is the domain within which the metadata applies. The resulting view function can be accessed externally by anyone. The resulting function overrides a function definition from the ISnowconeProjects interface.

Count

Interface: ISnowconeProjects

The number of projects that have been created using this contract.

The count is incremented with each new project created. The resulting ERC-721 token ID for each project is the newly incremented count value.

Definition

The resulting view function can be accessed externally by anyone. The resulting function overrides a function definition from the ISnowconeProjects interface.

createFor

Create a new project for the specified owner, which mints an NFT (ERC-721) into their wallet.

Anyone can create a project on an owner's behalf.

Definition

Arguments:

owner is the address that will be the owner of the project.

metadata is a struct containing metadata content about the project, and domain within which the metadata applies. The function can be accessed externally by anyone. The function overrides a function definition from the ISNWProjects interface. The function returns the token ID of the newly created project.

supportsInterface

Contract: SnowconeProjects

Interface: IERC165

ndicates if this contract adheres to the specified interface.

See {IERC165-supportsInterface}.

Definition

Read

Write

/**
  @notice
  The metadata for each project, which can be used across several domains.

  _projectId The ID of the project to which the metadata belongs.
  _domain The domain within which the metadata applies. Applications can use the domain namespace as they wish.
*/
mapping(uint256 => mapping(uint256 => string)) public override metadataContentOf;
/**
  @notice
  The number of projects that have been created using this contract.

  @dev
  The count is incremented with each new project created.
  The resulting ERC-721 token ID for each project is the newly incremented count value.
*/
uint256 public override count = 0;

function createFor(address _owner, SNWProjectMetadata calldata _metadata)
external
override
returns (uint256 projectId) { ... }
Arguments: _interfaceId is the ID of the interface to check for adherence to. The view function can be accessed externally by anyone, and internally within this contract. The view function does not alter state on the blockchain. The function overrides a function definition from the IERC165 interface. The function returns a flag indicating if this contract adheres to the specified interface. Body

Return true if the provided interface ID is in the list of interfaces this contract adheres to.

/**
  @notice
  Indicates if this contract adheres to the specified interface.

The bug bounty program is a way to incentivize the community to help identify potential vulnerabilities in the contract code. The rewards are categorized based on the severity and potential impact of the identified issue.

  1. Optimization: If you can suggest a way to make the operation more efficient, perhaps by reducing gas costs or improving computational efficiency, you can earn a reward of 0.5 ETH.

  2. Low Severity: If you identify a vulnerability that could lead to an inconvenience for a user of the protocol or for a protocol developer, but doesn't pose a serious risk to the protocol's functionality or users' funds, you can earn a reward of 1 ETH.

  3. High Severity: If you identify a vulnerability that could lead to data corruption or loss of funds, you can earn a reward of 5+ ETH. The exact amount will depend on the severity and potential impact of the issue.

Please note that the rewards are paid out in ETH and the actual USD value may vary based on the current market price of ETH.

function supportsInterface(bytes4 _interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { ... }
return
  _interfaceId == type(ISnowconeProjects).interfaceId

setMetadataOf

Allows a project owner to set the project's metadata content for a particular domain namespace.

Only a project's owner or operator can set its metadata.

Applications can use the domain namespace as they wish.

Definition

function setMetadataOf(uint256 _projectId, SNWProjectMetadata calldata _metadata)
  external
  override
  requirePermission(ownerOf(_projectId), _projectId, SNOWperations.SET_METADATA) { ... }

Arguments:

  • _projectId is the ID of the project whose metadata is being changed.

  • _metadata is the struct containing metadata content, and domain within which the metadata applies.

Through the requirePermission modifier, the function is only accessible by the project's owner, or from an operator that has been given the SNWOperations.SET_METADATA permission by the project owner for the provided _projectId.

The function overrides a function definition from the ISNWProjects interface. The function doesn't return anything.

Body

Internal references:

  • metadataContentOf

Emit a SetMetadataCid event with the relevant parameters.

Event references:

  • SetMetadata

setTokenUriResolver

Sets the address of the resolver used to retrieve the tokenURI of projects.

Definition

Arguments:

  • _newResolver is the address of the new resolver.

Through the onlyOwner modifier, this function can only be accessed by the address that owns this contract.

SetMetadata

Emitted from:

setMetadataOf Definition

projectId is the token ID of the NFT (ERC-721) that represents the project whose URI was set. metadata is the metadata that was associated with the project upon its creation. It can be found using the metadataContentOf property. caller is the address that issued the transaction within which the event was emitted.

SetTokenUriResolver

Emitted from:

setTokenUriResolver Definition

newResolver is the new URI resolver contract. caller is the address that issued the transaction within which the event was emitted.

Create

Emitted from:

createFor Definition

projectId is the token ID of the NFT (ERC-721) that was created to represent the project. owner is the address that owns the NFT (ERC-721) token representing the project. metadata is the metadata that was associated with the project upon its creation. It can be found using the metadataContentOf property. caller is the address that issued the transaction within which the event was emitted.

Contracts

Specifications

A contract can become a treasury pay delegate by adhering to ISnowconePayDelegate3_1_1:

When extending pay functionality with a delegate, the protocol will pass a SnowconeDidPayData3_1_1 to the didPay(...) function:

The msg.sender to the delegate will be the payment terminal that facilitated the payment.

||
_interfaceId == type(ISnowconeOperatable).interfaceId ||
super.supportsInterface(_interfaceId);
@dev
See {IERC165-supportsInterface}.
@param _interfaceId The ID of the interface to check for adherence to.
*/
function supportsInterface(bytes4 _interfaceId)
public
view
virtual
override(IERC165, ERC721)
returns (bool)
{
return
_interfaceId == type(ISnowconeProjects).interfaceId ||
_interfaceId == type(ISnowconeOperatable).interfaceId ||
super.supportsInterface(_interfaceId);
}
// Store the project's new metadata content within the specified domain.
metadataContentOf[_projectId][_metadata.domain] = _metadata.content;
emit SetMetadata(_projectId, _metadata, msg.sender);
event SetMetadata(uint256 indexed projectId, SnowconeProjectMetadata metadata, address caller);
event SetTokenUriResolver(ISnowconeTokenUriResolver indexed newResolver, address caller);
event Create(
  uint256 indexed projectId,
  address indexed owner,
  SnowconeProjectMetadata metadata,
  address caller
);
The function overrides a function definition from the ISNWProjects interface. The function doesn't return anything.

Body

Internal references:

  • tokenUriResolver

Emit a SetTokenUriResolver event with the relevant parameters.

Event references:

  • SetTokenUriResolver

function setTokenUriResolver(ISNWTokenUriResolver _newResolver) external override onlyOwner { ... }
/// Store the new resolver.
tokenUriResolver = _newResolver;
In payment terminals based on the SnowconePayoutRedemptionPaymentTerminal3_1_1, such as SnowconeETHPaymentTerminal3_1_1's and SnowconeERC20PaymentTerminal3_1_1's, the pay delegate hook gets called after the project's tokens have been minted and distributed. View the docs.

Ensure to only allow trusted contracts to access the didPay(...) transaction.

Attaching

New delegate contracts should be deployed independently. Once deployed, its address can be returned from a data source hook. See how to build a data source for more.

Examples

interface ISnowconePayDelegate3_1_1 is IERC165 {
  function didPay(SnowconeDidPayData3_1_1 calldata data) external payable;
}
struct SnowconeDidPayData3_1_1 {
    address payer;
    uint256 projectId;
    uint256 currentFundingCycleConfiguration;
    SnowconeTokenAmount amount;
    SnowconeTokenAmount forwardedAmount;
    uint256 projectTokenCount;
    address beneficiary;
    bool preferClaimedTokens;
    string memo;
    bytes dataSourceMetadata;
    bytes payerMetadata;
}

struct SnowconeTokenAmount {
  address token;
  uint256 value;
  uint256 decimals;
  uint256 currency;
}
emit SetTokenUriResolver(_newResolver, msg.sender);
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@snowcone-protocol/contracts-v2/contracts/interfaces/ISnowconeFundingCycleDataSource.sol';
import '@snowcone-protocol/contracts-v2/contracts/interfaces/ISnowconePayDelegate.sol';
import '@snowcone-protocol/contracts-v2/contracts/structs/SnowconeTokenAmount.sol';

contract NFTPayDelegate is ERC721, ISnowconeFundingCycleDataSource, ISnowconePayDelegate {
  error INVALID_PAYMENT_EVENT();

  ISnowconeDirectory directory;
  uint256 projectId;
  SnowconeTokenAmount contributionThreshold;
  uint256 supply;

  // This contract can be used as a funding cycle data source to ensure its didPay function is called once the payment has gone through.
  function payParams(SnowconePayParamsData calldata _data)
    external
    view
    override
    returns (
      uint256 weight,
      string memory memo,
      ISnowconePayDelegate delegate
    )
  {
    // Forward the received weight and memo, and use this contract as a pay delegate.
    return (_data.weight, _data.memo, ISnowconePayDelegate(address(this)));
  }

  // 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)));
  }

  constructor(ISnowconeDirectory _directory, uint256 _projectId, SnowconeTokenAmount _contributionThreshold, string calldata _name, string calldata _symbol) ERC721(_name, _symbol) {
    directory = _directory;
    projectId = _projectId;
  },

  // Called once the payment has gone through if the project's current funding cycle is using a data source that returns this delegate.
  function didPay(SnowconeDidPayData calldata _data) external override {
    // Make sure the caller is a terminal of the project, and the call is being made on behalf of an interaction with the correct project.
    if (
      !directory.isTerminalOf(projectId, ISnowconePaymentTerminal(msg.sender)) ||
      _data.projectId != projectId
    ) revert INVALID_PAYMENT_EVENT();

    // Make the contribution is being made in the expected token.
    if (_data.amount.token != contributionThreshold.token) return;

    // Make sure the values use the same number of decimals.
    if (_data.amount.decimals < contributionThreshold.decimals) return;

    // Make sure the threshold is met.
    if (_data.amount.value < contributionThreshold.value) return;

    uint256 _tokenId = ++supply;

    _mint(_data.beneficiary, _tokenId);
  }
}