Building

Overview

A CosmWasm contract on DeFund only needs to interact with one message on DeFund in order to build as complex of a trading strategy as needed. DeFund automatically handles everything else for you. This message is the MsgEditFund message. This msg only allows a Cosmwasm contract to edit a fund. No one else is ever able to edit the fund. Only the contract. This is by design, as it keeps DeFund completely permissionless. If you need to make changes to the fund (aka the contract), you must upgrade the contract via a migration.

See the Migrate section for more details on migration.

See this repo for an example Cosmwasm dETF.

CosmWasm Bindings

The following are the module Msg's and Queries exposed via Cosmwasm. If you are a team that needs access to another message and/or query, either contact us at build@defund.app or push a PR/Issue on Github.

Messages

  • MsgEditFund - msg within the ETF module that edits the underlying fund's Holdings.

    • This message can be used in a number of ways. For example, if your contract needed to move exposure from 33% asset one, 33% asset two & 34% asset three into 66% asset one and 34% asset three, all you would have to do in the contract is submit a MsgEditFund that changed the Holding % for asset two to 0 and asset one to 66. At the next block, DeFund (through rebalancing) would then move the assets automatically for you.

  • MsgBrokerTransfer (coming soon) - msg within the Broker module that transfers an asset directly from one fund broker address to another broker address.

    • When you send a MsgBrokerTransfer, your contract must implement an ExecuteMsg:OnMsgBrokerTransferResponse entrypoint. DeFund funnels the response from this request into the contract through this entrypoint for you to run any custom logic you need.

  • MsgBrokerTrade (coming soon) - msg within Broker module that runs a swap/trade on the remote broker.

    • When you send a MsgBrokerTrade, your contract must implement an ExecuteMsg:OnMsgBrokerTradeResponse entrypoint. DeFund funnels the response from this request into the contract through this entrypoint for you to run any custom logic you need.

Queries

  • GetFund

  • GetFunds

  • GetFundPrice

  • GetBrokers

  • GetBroker

How To Build

When you build a dETF contract on DeFund, all you have to do is manage the fund.Holding state of your dETF. The structure of this fund.Holding state within the fund is the following:

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct Fund {
    ...
    pub holdings: Vec<Holding>,
    ...
}

The structure of the Holding type is the following:

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct Holding {
    pub token: String,
    pub percent: i64,
    pub pool_id: u64,
    pub broker_id: String,
    pub asset_type: String,
}

This holding type is what you directly interact with through the MsgEditFund message. So to build your dETF, you just build your strategy, whatever that might be, and change the list of holding as you need like the following:

let res =
    Response::new()
    .add_message(DefundMsg::EditFund { 
        symbol: fund.symbol, 
        holdings: update_holdings,
    });

Passive dETFs

A dETF on DeFund created with the type set as passive will be treated as such, a passive fund. When you build custom contracts to plug into a passive dETF, the only way to customize this fund through CosmWasm contracts is by specifying the Holding type as a contract address (although, this is not implemented quite yet). If the holding type is detected as a CosmWasm contract address, DeFund will skip the auto-rebalancing for just this asset and run the contract through the entry point instead.

You can thus think of this as a way to customize auto-rebalancing at the asset level to your exact needs if you need to.

Active dETFs

A dETF set to active has no auto rebalancing on any asset, no matter the type unlike passive. In fact, the entire rebalancing is skipped, and instead, DeFund runs the contract through the contract entry point at each rebalance height. You can think of this as a fully customized active fund. Use cases for active may include: staking dETFs, data-driven dETFs, arbitrage dETFs, statistical arbitrage dETFs, market cap weighted dETFs, etc.

Last updated