Claimdrop Contract V2

The Claimdrop Contract V2 is a smart contract designed to distribute tokens to a list of addresses in a secure and efficient manner. Based on V1, this contract's implementation differs by a few factors, such as using a batch upload mechanism to add a list of allocations, with addresses and their corresponding token amounts.

Features

  • Batch upload allocations. Batch upload can only be done before the campaign starts, afterwards, the feature is disabled.

  • Lump sum and/or linear vesting distribution. Two distribution types are supported simultaneously. For instance one could be a lump sum distribution and the other could be a linear vesting distribution.

  • Only one campaign per contract. If there's an error with the current campaign, the owner can close the campaign, retrieving all the unclaimed tokens back. It's possible to get a snapshot of all the tokens claimed up to that point with the Claimed query, then create a new contract/campaign with the right data.

  • The owner is the only one who can create campaigns.

  • Anyone can top up the campaign by sending funds to the contract by using a BankMsg.

  • The owner can close the campaign at any point before the campaign ends. When a campaign is ended, the owner will receive the remaining, unclaimed tokens in the campaign.

  • Only a single claim entry per address is allowed.

  • Addresses are added as strings, in case there are users entitled to claim but still haven't bridged from Ethereum to MANTRA, a placeholder can be used for those addresses.

  • Ability to replace an address in the allocation's registry. When this occurs, the claims performed by the "old" wallet are attached to the new address, same as the original allocation entry. The entries for the old wallet are removed.

  • Ability to remove an address from the allocation list.

  • Coin agnostic, any native coin is supported.

  • Ability to blacklist addresses (in case of hacked for instance). Blacklisted wallets cannot claim.

  • The owner (of the contract) is the only one able to do all permissioned actions, i.e. create a campaign, close a campaign, blacklist users, batch upload addresses.

  • Ability to make partial claims.

How it works

The Claimdrop Contract V2 is meant to host a single airdrop campaign per contract. When instantiating the contract, an owner can be specified. Only the owner can:

  • Create a new campaign.

  • Batch upload allocations.

  • Blacklist an address.

  • Replace or remove an address from allocation list.

  • Close campaign, retriving the remaining funds in the contract.

If there's a mistake on the token distribution, i.e. the airdrop data was incorrect, the owner can remove the addresses that were incorrect and add the right allocations with another message.

Instantiate

Instantiates an instance of the claimdrop contract.

{
  "owner": "mantra1..."
}
Key
Type
Description

owner

Option<String>

The owner of the contract. If none is provided, the address instantiating the contract becomes the owner.

ExecuteMsg

ManageCampaign

Manages a campaign based on the action, which can be:

  • CreateCampaign: Creates a new airdrop campaign, making sure all params are correct. Only the contract owner can perform this action.

  • CloseCampaign: Closes the campaign. The remaining unclaimed funds are returned to the owner of the campaign. Only the contract owner can perform this action.

Once created, the campaign is stored in the CAMPAIGN item.

{
  "manage_campaign": {
    "action": {
      "create_campaign": {
        "params": {
          "name": "Airdrop",
          "description": "This is an airdrop description.",
          "reward_denom": "uom",
          "total_reward": {
            "denom": "uom",
            "amount": "888888888888"
          },
          "distribution_type": [
            {
              "lump_sum": {
                "percentage": "0.25",
                "start_time": 1571797419
              }
            },
            {
              "linear_vesting": {
                "percentage": "0.75",
                "start_time": 1572402219,
                "end_time": 1573007019,
                "cliff_duration": 86400
              }
            }
          ],
          "start_time": 1571797419,
          "end_time": 1573007019
        }
      }
    }
  }
}
Key
Type
Description

name

String

The name of the campaign. The name cannot be empty nor above 200 chars in length.

description

String

The description of the campaign. The description cannot be empty nor above 2000 chars in length.

reward_denom

String

The denom to be distributed as reward by the campaign.

total_reward

Coin

The total amount of the reward asset that is intended to be allocated to the campaign.

distribution_type

Vec<DistributionType>

The distribution types. It can be two at most, and it can be a combination of LumpSum and LinearVesting. The percentage of both distributions needs to be equal to 100%, and their start time needs to be in the future.

start_time

u64

The campaign start time (unix timestamp), in seconds.

end_time

u64

The campaign end timestamp (unix timestamp), in seconds.

Claim

Claims rewards from a campaign.

{
  "claim": {
    "receiver": "mantra1...",
    "amount": "88888"
  }
}
Key
Type
Description

receiver

Option<String>

The receiver address of the claimed rewards. If not set, the sender of the message will be the receiver. This is useful for allowing a contract to do the claim operation on behalf of a user.

amount

Option<Uint128>

The amount to claim. If not set, all available tokens will be claimed.

AddAllocations

Adds a batch of addresses and their allocations. This can only be done by the owner before the campaign has started.

{
  "add_allocations": {
    "allocations": [
      [
        "mantra1...",
        "100000"
      ],
      [
        "mantra1...",
        "200000"
      ]
    ]
  }
}
Key
Type
Description

allocations

Vec<(String, Uint128)>

Vector of (address, amount) pairs.

ReplaceAddress

Replaces an address in the allocation list. This can be done at any time by the owner.

{
  "replace_address": {
    "old_address": "mantra1...",
    "new_address": "mantra1..."
  }
}
Key
Type
Description

old_address

String

The old address to replace.

new_address

String

The new address to use.

RemoveAddress

Removes an address from the allocation list. This can only be done by the owner before the campaign has started.

{
  "remove_address": {
    "address": "mantra1..."
  }
}
Key
Type
Description

address

String

The address to remove.

BlacklistAddress

Blacklists or unblacklists an address. This can be done at any time by the owner.

{
  "blacklist_address": {
    "address": "mantra1...",
    "blacklist": true
  }
}
Key
Type
Description

address

String

The address to blacklist/unblacklist.

blacklist

bool

Whether to blacklist or unblacklist.

UpdateOwnership(::cw_ownable::Action)

Implements cw_ownable. Updates the contract's ownership. ::cw_ownable::Action can be TransferOwnership,AcceptOwnership and RenounceOwnership.

Propose to transfer the contract's ownership to another account, optionally with an expiry time. Can only be called by the contract's current owner. Any existing pending ownership transfer is overwritten.

{
  "update_ownership": {
    "transfer_ownership": {
      "new_owner": "mantra1...",
      "expiry": {
        "at_height": "424242424242"
      }
    }
  }
}
Key
Type
Description

new_owner

String

The new owner proposed,

expiry

Option<Expiration>

Optional expiration time parameter.

QueryMsg

Campaign

Get the airdrop campaign.

{
  "campaign": {}
}

Rewards

Get the rewards for a specific campaign and receiver address.

{
  "rewards": {
    "receiver": "mantra1..."
  }
}
Key
Type
Description

receiver

String

The address to get the rewards for.

Claimed

Get the total amount of tokens claimed on the campaign.

{
  "claimed": {
    "address": "mantra1...",
    "start_from": "mantra1...",
    "limit": 50
  }
}
Key
Type
Description

address

Option<String>

If provided, it will return the tokens claimed by the specified address.

start_from

Option<String>

If provided, the address to start querying from. Used for paginating results.

limit

Option<u16>

The maximum number of items to return. If not set, the default value is used. Used for paginating results.

Allocations

Get the allocation for an address.

{
  "allocations": {
    "address": "mantra1...",
    "start_after": "mantra1...",
    "limit": 50
  }
}
Key
Type
Description

address

Option<String>

If provided, it will return the allocation for the specified address.

start_after

Option<String>

If provided, the address to start querying from. Used for paginating results.

limit

Option<u16>

The maximum number of items to return. If not set, the default value is used. Used for paginating results.

IsBlacklisted

Check if an address is blacklisted.

{
  "is_blacklisted": {
    "address": "mantra1..."
  }
}
Key
Type
Description

address

String

The address to check for.

Ownership

Returns the ownership of the contract.

{
  "ownership": {}
}

Last updated