Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
/**
@notice
The contract resolving each project ID to its ERC721 URI.
*/
ISnowconeTokenUriResolver public override tokenUriResolver;
constructor(ISnowconeOperatorStore _operatorStore)
ERC721('Snowcone Projects', 'SNOWCONE')
EIP712('Snowcone Projects', '1')
SnowconeOperatable(_operatorStore)
{}
/**
@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) { ... }/**
@notice
Indicates if this contract adheres to the specified interface.
function supportsInterface(bytes4 _interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { ... }return
_interfaceId == type(ISnowconeProjects).interfaceId
function setMetadataOf(uint256 _projectId, SNWProjectMetadata calldata _metadata)
external
override
requirePermission(ownerOf(_projectId), _projectId, SNOWperations.SET_METADATA) { ... }
// 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
);
function setTokenUriResolver(ISNWTokenUriResolver _newResolver) external override onlyOwner { ... }
/// Store the new resolver.
tokenUriResolver = _newResolver;
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);
}
}