Crowdfund

Introduction

The Crowdfund ADO is a smart contract that allows users to start a campaign and raise funds for their projects/goal by selling NFTs.

Each campaign can contain multiple tiers for different levels of support. For example you could have a bronze, silver, and gold tier for your crowdfund each having a specified price. All NFTs of the same tier share the same metadata.

When the campaign is over, the user can claim their NFT that corresponds to the tier they have purchased. In case the crowdfund does not reach its set goal, users would get refunds for their purchases. The sale can be performed using either native tokens or CW20 tokens depending on what the owner wants.

The NFTs are minted at the end of the sale. Each NFT will take the metadata assigned to its tier.

The minter of the CW721 linked to the Crowdfund needs to be specified as the Crowdfund ADO to be able to mint the NFTs to the users when the crowdfunding is over.

Ado_type: crowdfund

Version: 2.0.2-beta.1

InstantiateMsg

pub struct InstantiateMsg {
    pub campaign_config: CampaignConfig,
    pub tiers: Vec<Tier>,
    pub kernel_address: String,
    pub owner: Option<String>,
}
NameTypeDesctription

campaign_confing

The configurations for the campaign.

tiers

Vec<Tier>

Defines the tiers available for purchase in the campaign.

kernel_address

String

Contract address of the kernel contract to be used for AMP messaging. Kernel contract address can be found in our deployed contracts.

owner

Option<String>

Optional address to specify as the owner of the ADO being created. Defaults to the sender if not specified.

CampaignConfig

Struct containing all of the campaign's configurations.

pub struct CampaignConfig {
    pub title: String,
    pub description: String,
    pub banner: String,
    pub url: String,
    pub token_address: AndrAddr,
    pub denom: Asset,
    pub withdrawal_recipient: Recipient,
    pub soft_cap: Option<Uint128>,
    pub hard_cap: Option<Uint128>,
}
NameTypeDesctription

title

String

The title of the campaign. Maximum length for the title is 64 characters.

description

String

A description about the campaign.

banner

String

URL pointing to the campaign's banner image.

url

String

URL pointing to the campaign's website.

token_address

The address of the CW721 contract whose NFTs will be sold in the campaign.

denom

The type of funds accepted to buy the NFT tiers in the campaign.

withdrawal_recipient

Recipient

The address to receive the funds from the campaign proceeds.

soft_cap

Option<Uint128>

An optional minimum amount of funds to be raised by the campaign for it to be considered successfull. Failing to meet this cap will result in refunds for the users.

hard_cap

Option<Uint128>

An optional maximum amount of funds that can be raised by the campaign.

Tier

Struct that defines a tier for the campaign.

pub struct Tier {
    pub level: Uint64,
    pub label: String,
    pub price: Uint128,
    pub limit: Option<Uint128>,
    pub metadata: TierMetaData,
}
NameTypeDescription

level

Uint64

The tier level. For example 1 for the highest tier, 2 for seconds highest etc...

label

String

A label to assign to the tier.

price

Uint128

The amount of denom needed to purchase this tier.

limit

Option<Uint128>

A limit to the number of NFTs available for this tier. Defaults to none if not specified.

sold_amount

Uint128

Field used to for queries to get the amount sold for each tier. Should be set to 0.

metadata

The metadata for this tier.

TierMetadata

pub struct TierMetaData {
    pub token_uri: Option<String>,
    pub extension: TokenExtension,
}
NameTypeDescription

token_uri

Option<String>

URI pointing to the NFT metadata. You can read more about the NFT token URI and metadata standards here.

extension

Any custom extension used by this contract. Here we use TokenExtension.

TokenExtension

Extension that can be added to an NFT when minting.

pub struct TokenExtension {
   pub publisher: String,
}
NameTypeDescription

publisher

String

The entity to assign as the publisher of the NFT e.g. "Andromeda" or "Bob". (Immutable).

ExecuteMsg

AddTier

Adds a new tier to the campaign.

Can only be used if the campaign has not started yet.

Only available to the contract owner.

pub enum ExecuteMsg {
    AddTier { tier: Tier },
    }
NameType Description

tier

The tier configurations.

UpdateTier

Updates the configurations of a previously set tier.

Can only be used if the campaign has not started yet.

Updates the tier with the for the specified level.

Only available to the contract owner.

pub enum ExecuteMsg {
    UpdateTier { tier: Tier },
    }
NameType Description

tier

The new tier configurations.

RemoveTier

Removes the tier with the specified level.

Can onluy be used if the campaign has not started yet.

Only available to the contract owner.

pub enum ExecuteMsg {
 RemoveTier { level: Uint64 },
 }
NameTypeDescription

level

Uint64

The tier level to remove from the campaign.

StartCampaign

Starts the crowdfunding campaign so that users are able to start purchasing tiers when the start_time is reached.

pub enum ExecuteMsg {
  StartCampaign {
        start_time: Option<MillisecondsExpiration>,
        end_time: MillisecondsExpiration,
        presale: Option<Vec<PresaleTierOrder>>,
    },
}
NameTypeDescription

start_time

Optoion<MillisecondsExpiration>

The time that the campaign opens up for purchases.

end_time

MillisecondsExpiration

The time that the campaign ends.

presale

Option<Vec<PresaleTierOrder>

A list of preorders for the campaign. The address that has preordered can directly claim their NFT.

PresaleTierOrder

pub struct PresaleTierOrder {
    pub level: Uint64,
    pub amount: Uint128,
    pub orderer: Addr,
}

level

Uint64

The tier level preordered.

amount

Uint128

The number of NFTs preordered for the specified level.

orderer

Addr

The address of the user that preordered the tier NFT.

PurchaseTiers (Native)

Purchase a tier in the campaign using native funds.

Make sure to attach the required funds along with the message.

Can only be called if the campaign is ongoing.

pub enum ExecuteMsg {
PurchaseTiers {
 orders: Vec<SimpleTierOrder> 
   },
}
NameType Description

orders

The tiers to purchase from the campaign.

SimpleTierOrders

pub struct SimpleTierOrder {
    pub level: Uint64,
    pub amount: Uint128,
}
NameType Description

level

Uint64

The tier level to purchase from.

amount

Uint128

How many NFTs to but from the specified level.

Receive

Receives tokens from a CW20 Send message to be used to purchase a tier in the campaign.

This message is not called by the user on this ADO, but is the case that handles receiving CW20 tokens from a CW20 ADO.

The JSON representation of the PurchaseTiers message should be base64 encoded and specified as the msg field for the Send execute.

pub enum ExecuteMsg {
     Receive(Cw20ReceiveMsg),
    }
    
pub struct Cw20ReceiveMsg {
    pub sender: String,
    pub amount: Uint128,
    pub msg: Binary,
}

pub enum Cw20HookMsg {
    PurchaseTiers { orders: Vec<SimpleTierOrder> },
}

In order to bid on an auction using a CW20, you need to define the message of the Cw20ReceiveMsg as a Cw721HookMsg as a base64 encoding of the JSON version.

PurchaseTiers (CW20)

Purchase a tier in the campaign using the sent CW20 tokens.

Can only be called if the campaign is ongoing.

pub enum ExecuteMsg {
PurchaseTiers {
 orders: Vec<SimpleTierOrder> 
   },
}
NameType Description

orders

The tiers to purchase from the campaign.

Claim

Claim the NFTs purchased in the campaign. If the campaign was not successfullm the message will issue a refund for the user.

Users can only claim when the campaign is over or if it was unsuccessfull.

pub enum ExecuteMsg {
    Claim{},
    }

EndCampaign

Ends the campaign.

Only available to the contract owner.

A campaign can be ended if it is ongoing and has hit the soft_cap or before it starts.

pub enum ExecuteMsg {
      EndCampaign {},
      }

DiscardCampaign

Discards a campaign. Used in case of emergencies where the owner discovers a mistake in the configurations.

Only available to the contract owner.

A campaign can be discarded if it is ongoing or before it starts.

pub enum ExecuteMsg {
     DiscardCampaign {},
     }

Base Executes

The rest of the execute messages can be found in the ADO Base section.

QueryMsg

CampaignSummary

Gets a summary for all the campaign information.

pub enum QueryMsg {
    #[returns(CampaignSummaryResponse)]
    CampaignSummary {},
    }

CampaignSummaryResponse

pub struct CampaignSummaryResponse {
    pub title: String,
    pub description: String,
    pub banner: String,
    pub url: String,
    pub token_address: AndrAddr,
    pub denom: Asset,
    pub withdrawal_recipient: Recipient,
    pub soft_cap: Option<Uint128>,
    pub hard_cap: Option<Uint128>,
    pub start_time: Option<MillisecondsExpiration>,
    pub end_time: MillisecondsExpiration,
    // Current Status
    pub current_stage: String,
    pub current_cap: u128,
}

current_stage: A campaign can be one of four stages.

#[cw_serde]
pub enum CampaignStage {
    /// Stage when all necessary environment is set to start campaign
    READY,
    /// Stage when campaign is being carried out
    ONGOING,
    /// Stage when campaign is finished successfully
    SUCCESS,
    /// Stage when campaign failed to meet the target cap before expiration
    FAILED,
}

current_cap: The current amount of capital made by the campaign.

The rest of the fields are the same sa the ones set at instantiation.

TierOrders

Gets a summary for all the campaign information.

pub enum QueryMsg {
    #[returns(TierOrdersResponse)]
    TierOrders {
        orderer: String,
        start_after: Option<u64>,
        limit: Option<u32>,
        order_by: Option<OrderBy>,
    },
}
NameTypeDescription

orderer

String

The address of the user we are getting the orders for.

start_after

Option<u64>

Optional parameter to indicate the starting point for pagination, based on the level of the TierOrder.

limit

Option<u32>

Optional parameter to limit the number of results.

order_by

Option<OrderBy>

Optional parameter to specify the ordering of the results.

OrderBy

pub enum OrderBy {
    Asc,
    Desc,
}

TierOrdersResponse

pub struct TierOrdersResponse {
    pub orders: Vec<SimpleTierOrder>,
}

pub struct SimpleTierOrder {
    // The tier level
    pub level: Uint64,
    // The number of NFTs sold for this tier level
    pub amount: Uint128,
}

Tiers

Gets a summary for all the campaign tiers.

pub enum QueryMsg {
    #[returns(TiersResponse)]
    Tiers {
        start_after: Option<u64>,
        limit: Option<u32>,
        order_by: Option<OrderBy>,
    },
}
NameType

start_after

Option<u64>

Optional parameter to indicate the starting point for pagination, based on the level of the TierOrder.

limit

Option<u32>

Optional parameter to limit the number of results.

order_by

Option<OrderBy>

Optional parameter to specify the ordering of the results.

TierResponse

pub struct TiersResponse {
    pub tiers: Vec<Tier>,
}

Returns a Tier struct for every available tier.

Base Queries

The rest of the query messages can be found in the ADO Base section.

Additional Resources

GithubWebsite