Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
# command linenpm install @Snowcones/snowcones-icy-contracts/const contract = require(`@Snowcones/snowcones-icy-contracts/deployments/${network}/${contractName}.json`)import '@Snowcone/snowcones-icy-contracts/contracts/[file-path].sol'interface ISnowconeSplitAllocator {
function allocate(SnowconeSplitAllocationData calldata _data) external payable;
}
struct SnowconeSplitAllocationData {
address token;
uint256 amount;
uint256 decimals;
uint256 projectId;
uint256 group;
SnowconeSplit split;
}
struct SnowconeSplit {
bool preferClaimed;
bool preferAddToBalance;
uint256 percent;
uint256 projectId;
address payable beneficiary;
uint256 lockedUntil;
ISnowconeSplitAllocator allocator;
}
interface ISNWPayDelegate3_1_1 is IERC165 {
function didPay(SNWDidPayData3_1_1 calldata data) external payable;
}
struct SNWDidPayData3_1_1 {
address payer;
uint256 projectId;
uint256 currentFundingCycleConfiguration;
SNWTokenAmount amount;
SNWTokenAmount forwardedAmount;
uint256 projectTokenCount;
address beneficiary;
bool preferClaimedTokens;
string memo;
bytes dataSourceMetadata;
bytes payerMetadata;
}
struct SNWTokenAmount {
address token;
uint256 value;
uint256 decimals;
uint256 currency;
}
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@snx-protocol/contracts-v2/contracts/interfaces/ISNWFundingCycleDataSource.sol';
import '@snx-protocol/contracts-v2/contracts/interfaces/ISNWPayDelegate.sol';
import '@snx-protocol/contracts-v2/contracts/structs/SNWTokenAmount.sol';
contract NFTPayDelegate is ERC721, ISNWFundingCycleDataSource, ISNWPayDelegate {
error INVALID_PAYMENT_EVENT();
ISNWDirectory directory;
uint256 projectId;
SNWTokenAmount 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(SNWPayParamsData calldata _data)
external
view
override
returns (
uint256 weight,
string memory memo,
ISNWPayDelegate delegate
)
{
// Forward the received weight and memo, and use this contract as a pay delegate.
return (_data.weight, _data.memo, ISNWPayDelegate(address(this)));
}
// This is unused but needs to be included to fulfill ISNWFundingCycleDataSource.
function redeemParams(SNWRedeemParamsData calldata _data)
external
pure
override
returns (
uint256 reclaimAmount,
string memory memo,
ISNWRedemptionDelegate delegate
)
{
// Return the default values.
return (_data.reclaimAmount.value, _data.memo, ISNWRedemptionDelegate(address(0)));
}
constructor(ISNWDirectory _directory, uint256 _projectId, SNWTokenAmount _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(SNWDidPayData 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, ISNWPaymentTerminal(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);
}
}
/**
@member id The tier's ID.
@member contributionFloor The minimum contribution to qualify for this tier.
@member lockedUntil The time up to which this tier cannot be removed or paused.
@member remainingQuantity Remaining number of tokens in this tier. Together with idCeiling this enables for consecutive, increasing token ids to be issued to contributors.
@member initialQuantity The initial `remainingAllowance` value when the tier was set.
@member votingUnits The amount of voting significance to give this tier compared to others.
@member reservedRate The number of minted tokens needed in the tier to allow for minting another reserved token.
@member reservedRateBeneficiary The beneificary of the reserved tokens for this tier.
@member encodedIPFSUri The URI to use for each token within the tier.
@member allowManualMint A flag indicating if the contract's owner can mint from this tier on demand.
*/
struct SNOW721Tier {
uint256 id;
uint256 contributionFloor;
uint256 lockedUntil;
uint256 remainingQuantity;
uint256 initialQuantity;
uint256 votingUnits;
uint256 reservedRate;
address reservedTokenBeneficiary;
bytes32 encodedIPFSUri;
bool allowManualMint;
}/**
@member contributionFloor The minimum contribution to qualify for this tier.
@member lockedUntil The time up to which this tier cannot be removed or paused.
@member initialQuantity The initial `remainingAllowance` value when the tier was set.
@member votingUnits The amount of voting significance to give this tier compared to others.
@memver reservedRate The number of minted tokens needed in the tier to allow for minting another reserved token.
@member reservedRateBeneficiary The beneificary of the reserved tokens for this tier.
@member encodedIPFSUri The URI to use for each token within the tier.
@member allowManualMint A flag indicating if the contract's owner can mint from this tier on demand.
@member shouldUseBeneficiaryAsDefault A flag indicating if the `reservedTokenBeneficiary` should be stored as the default beneficiary for all tiers.
*/
struct SNOW721TierParams {
uint256 contributionFloor;
uint256 lockedUntil;
uint256 initialQuantity;
uint256 votingUnits;
uint256 reservedRate;
address reservedTokenBeneficiary;
bytes32 encodedIPFSUri;
bool allowManualMint;
bool shouldUseBeneficiaryAsDefault;
}/**
@member tiers The tiers to set.
@member currency The currency that the tier contribution floors are denoted in.
@member decimals The number of decimals included in the tier contribution floor fixed point numbers.
@member prices A contract that exposes price feeds that can be used to resolved the value of a contributions that are sent in different currencies. Set to the zero address if payments must be made in `currency`.
*/
struct SNOW721PricingParams {
SNOW721TierParams[] tiers;
uint256 currency;
uint256 decimals;
SNOWPrices prices;
}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;
}
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);
}
}
constructor(ISnowconeOperatorStore _operatorStore)
ERC721('Snowcone Projects', 'SNOWCONE')
EIP712('Snowcone Projects', '1')
SnowconeOperatable(_operatorStore)
{}
function createFor(address _owner, SNWProjectMetadata calldata _metadata)
external
override
returns (uint256 projectId) { ... }query ProjectMetrics($Project: String! = "1-1") {
projects(where: { id: $Project }) {
createdAt
id
owner
projectId
totalPaid
totalRedeemed
metadataUri
handle
terminal
currentBalance
cv
}
}query ProjectPayments($ProjectId: String! = "2-1") {
projects(where: { id: $ProjectId }, first: 10) {
handle
payEvents(first: 20, orderBy: timestamp, orderDirection: desc) {
amount
caller
note
timestamp
txHash
}
}
}Continueinterface ISnowconeFundingCycleBallot {
function duration() external view returns (uint256);
function stateOf(
uint256 _projectId,
uint256 _configuration,
uint256 _start
) external view returns (SnowconeBallotState);
}interface ISnowconeRedemptionDelegate3_1_1 is IERC165 {
function didRedeem(SnowconeDidRedeemData3_1_1 calldata data) external payable;
}
struct SnowconeDidRedeemData3_1_1 {
address holder;
uint256 projectId;
uint256 currentFundingCycleConfiguration;
uint256 projectTokenCount;
SnowconeTokenAmount reclaimedAmount;
SnowconeTokenAmount forwardedAmount;
address payable beneficiary;
string memo;
bytes dataSourceMetadata;
bytes redeemerMetadata;
}
struct SnowconeTokenAmount {
address token;
uint256 value;
uint256 decimals;
uint256 currency;
}
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
);
}
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;
}
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;
}
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)));
}
}
/**
@notice
The contract resolving each project ID to its ERC721 URI.
*/
ISnowconeTokenUriResolver public override tokenUriResolver;
event SetMetadata(uint256 indexed projectId, SnowconeProjectMetadata metadata, address caller);
event Create(
uint256 indexed projectId,
address indexed owner,
SnowconeProjectMetadata metadata,
address caller
);
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);
/**
@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;
ProtocolV1LogPrintReservesEventDistributePayoutsEventevent SetTokenUriResolver(ISnowconeTokenUriResolver indexed newResolver, address caller);
function supportsInterface(bytes4 _interfaceId) public view return
_interfaceId == type(ISnowconeProjects).interfaceId ||
_interfaceId == type(ISnowconeOperatable).interfaceId ||
super.supportsInterface(_interfaceId);
/**
@notice
Indicates if this contract adheres to the specified interface.
@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);
}
/**
@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;
function setTokenUriResolver(ISNWTokenUriResolver _newResolver) external override onlyOwner { ... }
/// Store the new resolver.
tokenUriResolver = _newResolver;
emit SetTokenUriResolver(_newResolver, msg.sender);