Only this pageAll pages
Powered by GitBook
1 of 79

Interest Protocol Documentation

Loading...

Overview

Sui💧

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Movement

Loading...

Loading...

Loading...

Loading...

V3 (Soon)

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Airdrop

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

DeFi

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Governance

Loading...

Loading...

Loading...

Utils

Loading...

Loading...

Loading...

Loading...

Math

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Welcome to Interest Protocol

We are updating our documentation. If you have any urgent questions, please reach out to one of our social channels below.

Join us

  • Twitter

  • Medium

  • Telegram

  • Discord

Learn more

Suicoins

Suicoins serves as the utility layer for all tokens and NFTs on the Sui Network. Its features include:

  • A Swap feature powered by Aftermath Finance.

  • A DCA (Dollar Cost Averaging) tool.

  • An Airdrop feature for seamless reward distribution.

  • An Incinerator to help keep your wallet clean by removing unwanted tokens.

  • A Send feature powered by Mysten Lab's xkSend for efficient transfers.

  • A Merger to free up chain space and declutter your wallet by consolidating assets.

Swap

Suicoins now supports Smart Router Swapping, an advanced feature powered by our esteemed partner Aftermath Finance. This powerful tool ensures you always get the best rates for your swaps on the Sui Network.


Smart-Order Router (SOR)

The Smart-Order Router (SOR) is an innovative DEX aggregator designed for the Sui network. It provides users with optimal swap prices by connecting to multiple liquidity pools and decentralized exchanges (DEXes) in the ecosystem.

Key Features

  1. Comprehensive Aggregation

    • SOR searches every liquid DEX on Sui, ensuring the best possible swap rates.

    • As the DeFi ecosystem grows, SOR continuously integrates with new DEXes.

  2. Trade Optimization

    • Splits large trades across multiple DEXes and liquidity pools to minimize slippage and improve trade efficiency.

  3. Simplicity and Security

    • Leverages Sui’s Programmable Transaction Blocks (PTBs) to combine complex, multi-step swap routes into a single, secure transaction.

  4. Permissionless Composability

    • Integrates seamlessly with other dApps, wallets, and DeFi tools.

    • Current use cases include integrations with:

      • Nightly Wallet swaps

      • Scallop Tools

      • Suiba Telegram bot


Why Use SOR on Suicoins?

  • Best Rates, Every Time: SOR searches all DEXes on Sui to guarantee competitive trade prices.

  • One-Click Swaps: Even for complex transactions, only one user action is required.

  • Efficient and Reliable: SOR ensures minimal slippage by splitting large trades and optimizing liquidity utilization.

Supported Liquidity Pools and DEXes

The SOR connects to a wide range of liquidity pools and platforms, including:

  • Aftermath

  • DeepBook

  • Cetus

  • Turbos

  • FlowX

  • Kriya

  • Suiswap

  • BlueMove


How It Works

  1. Search for Liquidity: The SOR scans all integrated DEXes and liquidity pools to identify the best available trade paths.

  2. Optimize the Trade Path: For large trades, the SOR splits transactions into smaller sub-paths to minimize slippage.

  3. Batch Execution: Through Sui’s PTBs, the trade is executed in a single transaction, ensuring security and simplicity.


The Smart-Order Router (SOR) makes trading on Suicoins seamless, cost-efficient, and secure—empowering both traders and developers within the Sui ecosystem.

Fees

Suicoins has a swap fee of 0.25% on every Swap.

Memez

Soon~

Packages

MemezFun: 0x8ac848bd470e8fcf64899f9361b21fd07c2c6da06e28f1edb5cd596f245f866c ACL: 0x5d406d0307d260f6ffc01f87960b0c28b8c5c3f0e8e71897b1a924a757232179

Vesting: 0xdada5d84429db8d56a775593b2893fc030826055dc84fa47ccdfd4933a63d093

Witnesses: 0x06267071d0eecfb7d16418cb71da4c7b7941b28208a71086ff3e47731c2d263a

Migrator: 0x5dd8927889172a7227e081bb3cb77ce3af4c9021390f5bb47aec329efea6359c

Shared Objects

ACL

  • Id: 0x1b5397ee2f6f8ccfb26016c1ed996f25b2277acb9ed5173fa0bed386360960d8

  • Initial Shared Version: 384530228

MigratorList

  • Id: 0xc7530527c63a3bf6dfde19522409c0b93654fe55f9664ccb54b97b94f4c58b19

  • Initial Shared Version: 384530298

Version

  • Id: 0xd645a047027384fee98f52d32b5730a7de65e07e79b9df8afa09ee675b9f914c

  • Initial Shared Version: 384530298

Config

  • Id: 0x42136e28848781b5a0c5ff544b2df0af414588289200ee01d01fdb3b0a66a418

  • Initial Shared Version: 384530298

Libs 📚

Interest Math

IPX Coin Standard

Constant Product

BPS

Name
Object Id
Type

Package Id

Immutable

Name
Object Id
Type

Package Id

Immutable

Name
Object Id
Type

Package Id

Immutable

Name
Object Id
Type

Package Id

Immutable

0x0a885c86b868d83e5094ef8a34985d510a99f4dd1491d115297eb23cea427595
0x7ead93e49fe002193faec3d2e4a7b750e9e568b5d875cafe17fcb0dc672b075e
0x9257e52d7a6545900184082fe8ad41cc6f61c3c65c14cd9710357a83bf0e1490
0x861a5bc378c5a4cdb8ed680c8edf6e147427f776c3b0af0002abe508c2621998

Dollar-Cost Averaging (DCA)

The Dollar-Cost Averaging (DCA) feature on Suicoins allows users to buy into or sell out of tokens gradually over time, reducing the risks associated with market volatility. This feature is designed to provide a systematic approach to trading, making it an ideal choice for both beginners and experienced investors.


Key Features of DCA on Suicoins

  1. Automated Buy-In and Sell-Out Strategies

    • Users can automate their investments, purchasing or selling tokens at regular intervals based on their predefined preferences.

  2. Active and Historical Monitoring Tools

    • Active DCA Tracker: Monitor ongoing DCA activities in real time to ensure your strategies are on track.

    • Historical Data Analysis: Access detailed records of past DCA activities to study your trading performance and refine strategies.

  3. Risk Mitigation Through Averaging

    • Gradual buying and selling helps mitigate the impact of price volatility, making it easier to achieve long-term investment goals.

  4. User-Friendly Interface

    • Intuitive tools ensure that setting up, monitoring, and analyzing DCA strategies is seamless, even for those new to DeFi.


Benefits of Using DCA on Suicoins

  • Reduce Emotional Trading: By sticking to a systematic plan, users avoid impulsive decisions influenced by market swings.

  • Historical Insights: Leverage past DCA data to make informed adjustments to your trading strategies.

  • Flexibility: Customize the frequency, token pair, and amount to suit your financial goals.


How It Works

  1. Set Up a DCA Plan:

    • Select the token you want to buy or sell and set the frequency and amount.

  2. Monitor Active Plans:

    • Use the Active DCA Tracker to check the progress of ongoing strategies in real time.

    • Make adjustments as needed without disrupting the overall plan.

  3. Analyze Historical Data:

    • Review detailed records of completed DCA activities, including trade dates, amounts, and market conditions.

    • Use these insights to optimize future trading plans.


Why Use DCA on Suicoins?

  • Consistency in Trading: Build wealth over time by regularly investing regardless of market conditions.

  • Data-Driven Insights: Gain a deeper understanding of your trading habits and performance through robust historical data.

  • Ease of Use: Simplify complex trading strategies with Suicoins’ intuitive DCA tools.


The DCA feature on Suicoins empowers users to trade systematically and analyze their performance, fostering a disciplined and informed approach to cryptocurrency trading.

Fee

Suicoins has a 0,5% fee for DCA

Suiplay Airdrop

The Suiplay Airdrop feature enables users and projects to distribute rewards directly to holders of SuiPlay Soulbound NFTs. Whether rewarding Mythics, Exalted, or all Soulbound NFT holders, the Suicoins Airdrop Tool simplifies the process of targeted and efficient reward distribution.


Key Features

  1. Targeted Airdrop Distribution

    • Choose between specific groups:

      • Mythics Soulbound NFT Holders

      • Exalted Soulbound NFT Holders

      • All Soulbound NFT Holders

  2. Flexible Token Options

    • Distribute any supported token of your choice.

  3. Streamlined Process

    • An intuitive interface guides users through the setup, review, and execution of the airdrop.


How It Works

  1. Navigate to the Airdrop Tool:

    • Open the Suicoins and select the Airdrop section.

  2. Select the Delivery Method:

    • Choose SuiPlay Holders as the method of delivery.

  3. Choose the Recipient Group:

    • Select the group of SuiPlay Soulbound NFT holders to airdrop to:

      • Mythics

      • Exalted

      • Everyone

  4. Set Token and Amount:

    • Specify the token and the amount to be distributed to each recipient.

  5. Review and Confirm:

    • Double-check your transaction details.

    • Approve and confirm the transaction in your wallet.

In this example, we’ve successfully airdropped 0.001 SUI to each SuiPlay Soulbound NFT holder (Mythics and Exalted).

Fees

Suicoins charges 0.002 Sui per Suiplay Wallet Address.

Airdrop

The Suicoins Airdrop Tool provides a seamless way for projects and individuals to distribute tokens to specific users via CSV files, NFT collection holders, or custom addresses. Whether you need to reward thousands of wallets or target holders of a particular NFT collection, our tool makes the process straightforward and efficient.


Key Features

  • Flexible Delivery Options: Distribute tokens using CSV files, to NFT collection holders, or to custom addresses.

  • Batch Processing: Airdrops are divided into batches of 500 transactions. For instance, an airdrop to 1,000 wallets will require two batches, with the DApp prompting you to confirm one transaction per batch.


Methods of Delivery

1. CSV File Distribution

Distribute tokens to multiple wallet addresses with customizable amounts for each address. Follow these steps:

  1. Prepare a CSV file formatted as follows:

    Address
    Amount

    0x123...abc

    100

    0x456...def

    200

  2. Upload your prepared CSV file.

  3. Choose the token you wish to airdrop.

  4. Review and confirm the transactions in your wallet.


Airdrop to NFT Collection Holders

Easily distribute tokens to all holders of a specified NFT collection. Each NFT held acts as a multiplier for the drop amount. Here’s how to do it:

  1. Navigate to the Airdrop section and select the token you wish to distribute.

  2. Choose the NFT Collection option.

  3. Specify the token amount to be airdropped per NFT.

  4. Review and confirm the transaction in your wallet.

Note:

  • The distribution is proportional to the number of NFTs a wallet holds. For example, a holder with 3 NFTs will receive 3 times the specified amount.


Custom Address Airdrops

Send the same amount of tokens to multiple wallet addresses.

Steps to use this feature:

  1. Navigate to the Airdrop section and select the token you wish to airdrop.

  2. Choose the Custom Addresses option.

  3. Enter wallet addresses, one per line.

  4. Specify the token amount to distribute to each address.

  5. Review and confirm the transaction in your wallet.


Important

  • Batch Transactions: Airdrops are limited to 500 wallets per batch. For larger distributions, you’ll need to confirm multiple transactions.

  • Verification: After completing an airdrop, all details can be checked on the Sui Explorer.

Fees

Suicoins has a airdrop fee of 0.004 Sui per wallet address.

Incinerator

An innovative tool developed by IPXSui for the Sui Network, the Suicoins Incinerator automates asset burning on the Sui blockchain, simplifying the removal of unwanted NFTs, tokens, and objects from your Sui Wallet. This document provides an overview of its features, usage, and implementation details.


Overview

The Suicoins Incinerator is designed to streamline asset management by allowing users to "burn" or delete digital assets from their Sui Wallet. Whether clearing unwanted tokens, NFTs, or other assets, the Incinerator provides a seamless interface for bulk or individual deletions. This tool helps users declutter their wallets and reclaim Sui in some cases.

Key Features

  • Automated Burning: Burn assets in bulk or one-by-one with a single click. Say goodbye to manual transaction processes.

  • Space Optimization: Merges multiple assets into one and frees up blockchain space, especially useful when removing scam or unwanted objects.

  • Reclaim Sui: By freeing up space, you may recover Sui if the reclaimed value exceeds the transaction cost.

  • Clutter Management: Keep your wallet tidy by removing or merging assets you no longer need.

  • Enhanced Security: Integrated with suiet_walletGuardians to help users identify and eliminate scam assets.


Getting Started

  1. Access the Incinerator: Go to Suicoins Incinerator.

  2. Connect Your Wallet: Ensure you have a compatible wallet connected, such as the Suiet Wallet.

  3. Select Assets to Burn: Choose assets from your wallet for burning or merging.

  4. Confirm Action: Follow the prompts to confirm your selections for incineration.


Usage Guide

  1. Connect Wallet: After opening the Incinerator page, connect your Sui Wallet.

  2. Select Assets: Browse your assets, and select either "Bulk Burn" or individual burning options to manage them as desired.

  3. Merge Coins or Objects: Use the Incinerator to combine multiple assets into a single entity before burning. This frees up blockchain space.

  4. Send to 0x0 Address: Once merged, the Incinerator sends the asset to the 0x0 address, effectively removing it from circulation.

Sui does not natively support burning coins unless specifically implemented by the coin developer. For supported assets, Suicoins’ Incinerator merges and sends them to 0x0, similar to Ethereum and Binance.


⚠️ Important Warning

Be extremely cautious when using the Suicoins Incinerator, as incineration is an irreversible action. Once an asset is burned, it cannot be recovered. Ensure you are not accidentally burning legitimate assets. Verify each asset carefully before proceeding. Suicoins and IPXSui will not be liable for any accidental burns. We will not provide reimbursements for mistaken incinerations.


Technical Details

The Suicoins Incinerator enables asset management by consolidating multiple coins or objects into a single entity and removing them from circulation. This not only frees up wallet space but may also return Sui to the user if the combined asset value exceeds the transaction fees.

Space Optimization

On Suicoins, burning removes assets and may return Sui to the user by merging objects, provided the reclaimed value is higher than the transaction cost.


WalletGuardians Integration

The Incinerator is integrated with @suiet_walletGuardians, which identifies and labels scam assets, making it easier to manage and delete unwanted items from your wallet. This integration ensures a safer and more efficient burning experience for all users.

To learn more about suiet_walletGuardians and how it enhances asset detection, refer to the WalletGuardians GitHub repository.

Merger

Think of your wallet as a digital garage—cluttered with tiny amounts of leftover coins. The Suicoins Merger feature lets you tidy things up, combining small amounts of various tokens to free up space and potentially uncover hidden value.

It’s like finding a forgotten bill in your old jacket pocket or discovering spare change in your couch cushions—only cooler and crypto-focused.


Key Benefits of the Merger

  1. Wallet Optimization

    • Consolidate your wallet by merging tiny balances into more meaningful amounts.

    • Free up valuable space on the Sui Network.

  2. Discover Hidden Value

    • Combine overlooked small balances of coins and potentially score extra $SUI.

  3. User-Friendly and Efficient

    • A seamless process designed to help you manage your digital assets with minimal effort.


How It Works

  1. Access the Merger Tool:

    • Navigate to the Merger Tool on Suicoins.

  2. Select Coins to Merge:

    • Choose the tiny coin balances you want to consolidate.

  3. Execute the Merge:

    • Suicoins will combine the selected balances and free up wallet space.

    • Any additional value discovered (e.g., $SUI) will be credited to your wallet.


Why Use Suicoins Merger?

  • Simplify Your Wallet: No more managing countless tiny balances.

  • Optimize Network Space: Help reduce clutter on the Sui Network.

  • Find Hidden Rewards: Merge and unlock the potential of your unused crypto.


With Suicoins Merger, managing your crypto becomes simpler, tidier, and more rewarding. Start decluttering your wallet today at suicoins.com/merge.

Send

Suicoins integrates with Mysten Labs' zkSend to provide an innovative way to send and claim digital assets securely and anonymously. This feature supports any publicly transferrable asset and enables users to create claim links with ease.

Effortlessly send coins, NFTs, and other assets on the Sui Network in stealth mode within seconds.


Key Features

  1. Create zkSend Claim Links

    • Generate claimable links for secure and private transfers of assets.

    • Support for all publicly transferrable assets, including:

      • Coins

      • NFTs

      • Other digital tokens

  2. Two Modes of Usage

    • Simple Link: Combine multiple assets (e.g., coins, NFTs) into a single claimable link.

    • Bulk Link: Distribute a specific coin through multiple claimable links, ideal for batch transactions. (Note: This feature is exclusive to coins.)

  3. Anonymity and Speed

    • Send and claim assets in stealth mode, ensuring privacy.

    • Transactions are completed within seconds.


How It Works

  1. Choose a Mode:

    • Select either the Simple Link or Bulk Link option, depending on your transfer requirements.

  2. Prepare the Assets:

    • For Simple Link: Add various assets like coins and NFTs to be included in one claimable link.

    • For Bulk Link: Specify the coin and number of claimable links to create.

  3. Generate and Share the Link:

    • Suicoins will create a zkSend claim link based on your inputs.

    • Share the link with recipients for them to claim the assets.

  4. Claim Assets:

    • Recipients can use the provided link to claim their assets instantly and privately.


Implementation

Developers interested in implementing zkSend functionality can use the following resources:

Mysten Labs SDK:

Suicoins Open-Source Code:

sdk.mystenlabs.com/zksend
github.com/interest-protocol/sui-coins

Contracts

Memez.gg

MemeFi

MemeFi... what? Do you mean DeFi

MemeFi (Meme Coin + Finance) are DeFi applications designed specifically for meme coins. Meme coins have carved their presence in the web3 industry as a vehicle to grab attention, new users and build culture. We have seen social trends and memes spread world wide because of meme coins.

Dapps built for meme coins need to take into account their users are not afraid of risk, fees, high slippage nor volatility. They provide developers with the opportunity to explore new instruments as they are as constraint like in DeFi.

Ok, What is Memez.gg ?!

Memez.gg is an end to end protocol to launch, bootstrap liquidity and trade meme coins.

  • Memez.Fun is a virtual liquidity launchpad with three different distribution mechanisms to price meme coins and bootstrap liquidity.

  • Memez.Dex is an exchange designed to appreciate meme coins by implementing special mechanisms that benefit buyers and discourage sellers.

All Meme coins created on Memez use the

Official Links

  • https://www.memez.gg

  • https://x.com/memezdotgg

SDK

Overview

Typescript SDK to interact with Memez.gg contracts.

Installation

The sdk is available on the NPM registry.

npm i @interest-protocol/memez-fun-sdk

SDK

How to setup the SDK.

import { MemezFunSDK } from '@interest-protocol/memez-fun-sdk';

// Sets up with the default environment
// At the moment Memez is only deployed on testnet

const memezPumpTestnet = new MemezPumpSDK();
​
const memezStableTestnet = new MemezStableSDK();

Suicoins Terminal

Overview

🌐 terminal.suicoins.com

The Suicoins Terminal is an open-source, lightweight adaptation of the Suicoins Swap feature, designed to enable seamless, end-to-end cryptocurrency swaps that can be integrated effortlessly into your platform.

Benefits of the Suicoins Terminal:

  • Secure on-site trading on the Sui Network

  • Enhanced user convenience with no need to navigate away from your platform

  • Streamlined user experience to improve trust and engagement


Key Features

Predefined Configurations

Define input and output tokens easily for precise trading pair setups.

Restricted Trading Options

Restrict swaps to specific tokens for enhanced security and platform focus.


Trading Fees Structure

The Suicoins Terminal applies a simple fee structure for swaps:

  • 0.15% for Memecoin Project.

  • 0.15% for Suicoins.

These fees are automatically calculated and deducted during each transaction.


How to Integrate

Vanilla SDK Integration

Follow these steps to integrate the Vanilla SDK into your project:

Step 1: Add the SDK Script

Include the following script in your HTML file:

<script src="https://cdn.jsdelivr.net/npm/@interest-protocol/sui-coins-terminal-vanilla/dist/index.umd.js"></script>

Step 2: Add the Terminal Container

Add an empty <div> with the required id attribute to your code:

<div id="suicoins-terminal" class="terminal"></div>

Step 3: Initialize the Terminal

Initialize the Suicoins Terminal with your custom parameters:

<script>
  SuiCoinsTerminal({
    typeIn: "0x2::sui::SUI",
    projectAddress: "0xdb3a22be6a37c340c6fd3f67a7221dfb841c818442d856f5d17726f4bcf1c8af",
    typeOut: "0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP",
    slippage: 1,
  });
</script>

React SDK Integration

Step 1: Install the SDK

Use one of the following package managers to add the SDK to your React project:

pnpm add @interest-protocol/sui-coins-terminal  
# or  
yarn add @interest-protocol/sui-coins-terminal  
# or  
npm install @interest-protocol/sui-coins-terminal  

Step 2: Import and Configure the Terminal Component

Import the SwapTerminal component and configure it with the necessary parameters:

import { SwapTerminal } from "@interest-protocol/sui-coins-terminal";

const Terminal = () => (
  <SwapTerminal
    typeIn="0x2::sui::SUI"
    projectAddress="0xdb3a22be6a37c340c6fd3f67a7221dfb841c818442d856f5d17726f4bcf1c8af"
    typeOut="0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP"
    slippage="1"
  />
);

export default Terminal;

Visit terminal.suicoins.com to learn more and integrate the Suicoins Terminal into your platform.

For any questions or assistance, our team is here to help—don’t hesitate to reach out.


Memez.Fun

Virtual liquidity launchpad

Virtual ... what?

In layman terms, Memez.fun is a platform to launch meme coins and bootstrap liquidity. The protocol supports three launch strategies:

  • Auction (High Risk): It mimics a dutch auction in which the meme coin starts at a very high price and quickly declines until a fair price is found by traders.

  • Pump (High Risk): The traditional method pioneered by pump.fun. The coin starts at a floor price to avoid early buyers from having a very large advantage.

  • Stable (Low Risk): It provides a fixed trading price for the coin until the target sui amount is acquired. Unlike a normal presale platform, users can exit their position anytime before the target raise is reached.

Phases

The pools can be in three different phases:

Bonding

All pools start at this phase as soon as they are created. In this phase users are allowed to buy and sell freely.

Migrating

This is triggered once the pool collects enough Sui to migrate from Memez.fun to a DEX. During this time, no trading is allowed. Anyone can call the migration function to move the liquidity.

Migrated

It indicates that a pool has successfully migrated. No trading is allowed in this phase.

It is impossible to return to a previous phase.

Migration

All pools on Memez.fun migrate once a certain amount of Sui is accumulated. This is referred as Target Sui Amount. Once this requirement is meant the liquidity is moved from our platform to a DEX chosen by the deployer.

Closed Loop Tokens

If chosen by the deployer, Memez.Fun pools can issue a Closed Loop Token to prevent buyers from creating pools before migration. Read more about them here.

Miscellaneous

Dynamic Supply

Meme coins on Memez.fun can have any supply. The contracts do not enforce a supply of 1 billion as other launchpads. Moreover, all coins are burnable.

Upgradeable Metadata

Meme coins created on Memez.fun can have their metadata updated by the deployer.

  • Name

  • Symbol

  • Description

  • Icon

Interfaces

MemezPool

It represents a Memez Pool.

export interface MemezPool<T> {
  objectId: string;
  poolType: string;
  curveType: string;
  memeCoinType: string;
  quoteCoinType: string;
  usesTokenStandard: boolean;
  ipxMemeCoinTreasury: string;
  metadata: Record<string, string>;
  migrationWitness: string;
  progress: string;
  stateId: string;
  dynamicFieldDataId: string;
  curveState: T;
}
  • objectId: The Sui Object id of this pool.

  • poolType: The struct tag of the pool.

  • curveType: It denotes the possible variants of the pool. E.g. Stable, Auction and Pump.

  • memeCoinType: The struct tag of the Meme coin.

  • quoteCoinType: The struct tag of the Quote coin.

  • usesTokenStandard: Denotes if the pool uses the token standard.

  • ipxMemeCoinTreasury: The id of the Meme coin Treasury.

    • Check out the IPX Treasury standard

  • metadata: A map of the meme coin metadata.

  • migrationWitness: The struct tag of the migrator witness. It shows to which DEX the pool is going to migrate to.

  • progress: The current status of the pool. E.g. Bonding, Migrating or Migrated.

  • stateId: The id of of the state object to fetch the inner state.

  • dynamicFieldDataId: The id of the dynamic field holding the inner state.

  • curveState: The inner state related to the variant.

PumpState

Represents the state of the Pump Pool that will be saved in the property curveState in the Memez Pool.

export interface PumpState {
  devPurchase: bigint;
  liquidityProvision: bigint;
  migrationFee: bigint;
  virtualLiquidity: bigint;
  targetQuoteLiquidity: bigint;
  quoteBalance: bigint;
  memeBalance: bigint;
  burnTax: number;
  swapFee: number;
  allocation: Allocation
}
  • devPurchase: The coins bought by the developer.

  • liquidityProvision: The amount of meme coin that will be added liquidity.

  • migrationFee: The payment in Sui that will be charged during migration.

  • virtualLiquidity: The virtual Sui liquidity to set a floor price.

  • targetSuiLiquidity: The amount of Sui required to migrate.

  • quoteBalance: The current amount of Sui in the pool.

  • memeBalance: The amount of meme coin in the pool.

  • burnTax: The burn tax percentage in bps.

  • swapTax: The swap fee percentage in bps.

  • allocation: Balance of meme coins to be sent o stake holders after migration.

Network

An enum referring to the current network being used.

export enum Network {
  Mainnet = 'mainnet',
  Testnet = 'testnet',
}
  • Mainnet: Sui Network main net

  • Testnet: Sui Network test net.

Packages

An object containing the packages to interact with Memez.

export const PACKAGES = {
  [Network.Mainnet]: {
    MEMEZ_FUN: {
      original: normalizeSuiAddress('0x0'),
      latest: normalizeSuiAddress('0x0'),
    },
    ACL: {
      original: normalizeSuiAddress('0x0'),
      latest: normalizeSuiAddress('0x0'),
    },
    VESTING: {
      original: normalizeSuiAddress('0x0'),
      latest: normalizeSuiAddress('0x0'),
    },
    MEMEZ_MIGRATOR: {
      original: normalizeSuiAddress('0x0'),
      latest: normalizeSuiAddress('0x0'),
    },
    MEMEZ_WITNESS: {
      original: normalizeSuiAddress('0x0'),
      latest: normalizeSuiAddress('0x0'),
    },
  },
  [Network.Testnet]: {
    MEMEZ_FUN: {
      original: normalizeSuiAddress(
        '0x63fed690a1154cfc4b31658443227de047cf3d305179aa5836e177c9efa57854'
      ),
      latest: normalizeSuiAddress(
        '0x63fed690a1154cfc4b31658443227de047cf3d305179aa5836e177c9efa57854'
      ),
    },
    ACL: {
      original: normalizeSuiAddress(
        '0x5d406d0307d260f6ffc01f87960b0c28b8c5c3f0e8e71897b1a924a757232179'
      ),
      latest: normalizeSuiAddress(
        '0x5d406d0307d260f6ffc01f87960b0c28b8c5c3f0e8e71897b1a924a757232179'
      ),
    },
    VESTING: {
      original: normalizeSuiAddress(
        '0xdada5d84429db8d56a775593b2893fc030826055dc84fa47ccdfd4933a63d093'
      ),
      latest: normalizeSuiAddress(
        '0xdada5d84429db8d56a775593b2893fc030826055dc84fa47ccdfd4933a63d093'
      ),
    },
    MEMEZ_MIGRATOR: {
      original: normalizeSuiAddress(
        '0x1c709c9f80361a4fb32a122b46a7381f8f6cf267016fdbf6e87b04622ba3476b'
      ),
      latest: normalizeSuiAddress(
        '0x1c709c9f80361a4fb32a122b46a7381f8f6cf267016fdbf6e87b04622ba3476b'
      ),
    },
    MEMEZ_WITNESS: {
      original: normalizeSuiAddress(
        '0x06267071d0eecfb7d16418cb71da4c7b7941b28208a71086ff3e47731c2d263a'
      ),
      latest: normalizeSuiAddress(
        '0x06267071d0eecfb7d16418cb71da4c7b7941b28208a71086ff3e47731c2d263a'
      ),
    }
  },
};
  • MEMEZ_FUN: The address of the core Memez package.

  • ACL: The package of the Memez admin package.

  • VESTING: The package of the vesting package of Memez package.

  • MEMEZ_MIGRATOR: The package of the migrator.

  • MEMEZ_WITNESS: A package containing the configuration witnesses.

Shared Objects

An object containing the shared objects to interact with Memez. Each object has a mutable and immutable reference for optimization purposes.

export const SHARED_OBJECTS = {
  [Network.Mainnet]: {
    ACL: ({ mutable }: { mutable: boolean }) => ({
      objectId: normalizeSuiObjectId('0x0'),
      initialSharedVersion: '1',
      mutable,
    }),
    VERSION: ({ mutable }: { mutable: boolean }) => ({
      objectId: normalizeSuiObjectId('0x0'),
      initialSharedVersion: '1',
      mutable,
    }),
    CONFIG: ({ mutable }: { mutable: boolean }) => ({
      objectId: normalizeSuiObjectId('0x0'),
      initialSharedVersion: '1',
      mutable,
    }),
    MIGRATOR_LIST: ({ mutable }: { mutable: boolean }) => ({
      objectId: normalizeSuiObjectId('0x0'),
      initialSharedVersion: '1',
      mutable,
    }),
  } as const,
  [Network.Testnet]: {
    ACL: ({ mutable }: { mutable: boolean }) => ({
      objectId: normalizeSuiObjectId(
        '0x1b5397ee2f6f8ccfb26016c1ed996f25b2277acb9ed5173fa0bed386360960d8'
      ),
      initialSharedVersion: '384530228',
      mutable,
    }),
    MIGRATOR_LIST: ({ mutable }: { mutable: boolean }) => ({
      objectId: normalizeSuiObjectId(
        '0xf35e6124170d1c7618090bed501edd8fc5f8d8f2d053fbc5f12db93300491ab7'
      ),
      initialSharedVersion: '384530230',
      mutable,
    }),
    VERSION: ({ mutable }: { mutable: boolean }) => ({
      objectId: normalizeSuiObjectId(
        '0x0e74ece4efbc1a15b1ff5bd5653e13281f691b9db8faf669b13783ecc414c848'
      ),
      initialSharedVersion: '384530230',
      mutable,
    }),
    CONFIG: ({ mutable }: { mutable: boolean }) => ({
      objectId: normalizeSuiObjectId(
        '0xd7d747343106d3586f9d96dce4741702de9033875b007f4a485f6593b2e53d79'
      ),
      initialSharedVersion: '384530230',
      mutable,
    }),
  } as const,
};
  • ACL: Shared object holding the current whitelisted admins.

  • VERSION: Shared object containing the latest version of the package.

  • CONFIG: Shared object contain all different configurations:

    • Fees

    • Pump State

    • Stable State

    • Auction State

  • MIGRATION_LIST: Shared object contain the allowed migrators.

Config Keys

The configuration supports various values per integrator. For example the fees for Recrd and Default keys will have different values. This is set by the admin.

export const CONFIG_KEYS = {
  [Network.Mainnet]: {
    DEFAULT: '',
    RECRD: ''
  },
  [Network.Testnet]: {
    DEFAULT: `${PACKAGES[Network.Testnet].MEMEZ_FUN}::memez_config::DefaultKey`,
    RECRD: `${PACKAGES[Network.Testnet].MEMEZ_WITNESS.original}::memez_witness::Recrd`,
  },
} as const;
  • DEFAULT: This is key to get the default parameters.

  • DEFAULT: To be used by RECRD.

Migrator Witnesses

Record of the current allowed migrators.

export const MIGRATOR_WITNESSES = {
  [Network.Mainnet]: {
    TEST: '',
  },
  [Network.Testnet]: {
    TEST: `${PACKAGES[Network.Testnet].MEMEZ_MIGRATOR}::dummy::Witness`,
  },
} as const;
  • TEST: Currently we have a test migrator that returns the balances for testing purposes.

Coins on Memez.GG

Step by step Guide of Coins on Memez.

Configurable Features

When creating a coin, users define key attributes:

Basic Information

  • Coin Name – Unique identifier for the token.

  • Ticker – Short symbol (e.g., ROOT for Rootlets).

  • Description – Brief summary of the token’s purpose.

  • Logo – Custom image representing the coin.

Supply Settings

  • Total Supply – Initial token amount (supports up to 9 decimal places).

  • Maximum Supply – Hard cap on total token supply.

Advanced Features

  • Burnable – Tokens can be removed from circulation, with burn permissions configurable.

  • Mintable – Allows the deployer to create additional tokens up to the maximum supply.

  • Editable Metadata – Enables modifications to name, ticker, description, and logo after deployme

Creating Coin on Memez GG

On the video below we have launched a token with all the functionalities mentioned above. Here are the details of the token created:

  • Name: Kumo

  • Ticker: Kumo

  • Description: Kumo the cat

  • Supply: 1,000,000

  • Max Supply: 1000,000,000

  • Functions enabled: Burnable, Mintable and Editable

🎥 Watch the video for a step-by-step walkthrough.

Editing The Metadata

After creating a coin with the Edit function enabled, you can update its metadata at any time. Now, let's rebrand the Kumo coin we created earlier by updating the following details:

  • Name: Rootlets

  • Ticker: ROOT

  • Description: “Just Root it”

  • Image: A Rootlet PFP

🎥 Watch the video for the step-by-step walkthrough.

And just like that—within a few clicks, we’ve successfully rebranded the entire coin!

Managing Tokens: Burning & Minting

Now that you know how to create and change it's metadata, let's explore two important functions—burning and minting tokens. These actions allow you to manage the token supply dynamically.

Remember that when we created the token, we enabled the ability to burn and mint tokens, setting the initial supply to 1,000,000 and the max supply to 1,000,000,000. This means you can perform burns and mints freely within the range of 0 to 1,000,000,000 tokens.

On the video below, we'll use the rebranded Rootlets token to demonstrate both processes. In this case we will first mint 100,000 tokens and then mint the same amount.

Migrating a Coin from Suicoins to Memez GG

Introduction

In this guide, we will walk through the process of migrating a coin created on Suicoins to Memez GG. This migration ensures that the coin follows the IPX Coin Standard, gaining key functionalities such as:

  • Burning tokens

  • Minting new tokens

  • Editing metadata

By the end of this tutorial, your migrated coin will have all of these features.

Prerequisites

Before proceeding with the migration, ensure that:

  • The deployer owns the treasury cap. Without it, migration is not possible.

  • When creating a coin on Suicoins, you have chosen to keep the treasury cap. If it has been sent to a dead address, migration is not possible.

Step 1: Creating a Coin on Suicoins

  1. Navigate to Suicoins and click Create Token.

  2. Fill in the token details. For this tutorial, we will use the following example:

    • Name: Prime Machine

    • Ticker: PRIME

    • Description: Suii is the endgame and starts with Studio Mirai.

    • Image: Prime Machine #2059

    • Supply: 1 million tokens

  3. Important Step: Do not set a fixed supply. Setting a fixed supply sends the treasury cap to a dead address, preventing migration. By keeping a flexible supply, the treasury cap remains with the deployer.

  4. Confirm the transaction in your wallet.

Once confirmed, the token is successfully created on Suiicoins.

Step 2: Migrating to Memez GG

  1. Navigate to Memez GG and click Create Token, then select Migrate.

  2. Choose the token you wish to migrate (e.g., Prime Machine).

  3. Configure the token settings. Memez GG provides options similar to the token creation process but now includes the ability to enable all functionalities of the IPX Coin Standard. Enable:

    • Burning tokens

    • Minting new tokens

    • Editing metadata

  4. Set a new max supply (e.g., 1 billion tokens).

  5. Confirm the transaction in your wallet.

🎥 Watch the video for the step-by-step walkthrough.

The coin creation tool on allows users to generate their own custom tokens with a range of configurable options. This functionality enables individuals and projects to launch tokens tailored to their specific needs, whether for utility, governance, or community engagement.

This coin creation tool empowers users to design and launch tokens with flexibility while maintaining key security and governance controls. This tool uses the .

Memez GG
IPX Coin Standard

Migrators

Cetus

The Cetus migrator calls the function below to deploy a pool.

public fun create_pool_v2<CoinTypeA, CoinTypeB>(
        _config: &GlobalConfig,
        _pools: &mut Pools,
        _tick_spacing: u32,
        _initialize_price: u128,
        _url: String,
        _tick_lower_idx: u32,
        _tick_upper_idx: u32,
        _coin_a: Coin<CoinTypeA>,
        _coin_b: Coin<CoinTypeB>,
        _metadata_a: &CoinMetadata<CoinTypeA>,
        _metadata_b: &CoinMetadata<CoinTypeB>,
        _fix_amount_a: bool,
        _clock: &Clock,
        _ctx: &mut TxContext
):  (Position, Coin<CoinTypeA>, Coin<CoinTypeB>) {
        abort 0
}

The Cetus protocol is initiated with the following parameters:

  • Tick Spacing: 200.

    • Largest possible fee on Cetus.

  • Initialized Price: 63901395939770060 or 0.000012 Sui.

  • Tick Lower Index: 4294523696

  • Tick Upper Index: 443600

    • This is to ensure full range liquidity

  • Fix Amount A: true

    • The meme coin amount is fixed

We supply 5% of the total meme coin supply. E.g. If a coin has a supply of 1 billion, we add 50 million of value in coin_a. The Sui amount is configurable by the integrator.

Fees

Memez.gg has a versatile fee mechanism enforced by the contracts. Each integrator is able to customize their fees parameters.

The system supports 0 fees.

Fee Mechanism

Depending on the fee, it can be defined in basis points percentage or in a nominal value. The fees are collected by the stake holders depending on how the configuration is set.

Fees Configuration

Each fee below requires the following configuration:

  • Fee Value

  • Address of fee recipients

  • Percentage that each recipient should receive in basis points.

If we set the Creation Fee to 2 Sui and the recipients to be the following: Alice (20%), Bob (50%) and Jose (30%).

At pool creation, the contract will automatically send 0.4 Sui to Alice, 1 Sui to Bob and 0.6 Sui to Jose. The system supports dynamic fee recipients at pool creation and system enforced ones as well. For example, we can set that 20% of the creation fee always goes to the integrator, while the rest of the fees recipients are set dynamically at pool creation.

  • Creation: This fee is collected when a pool is created and it is defined in a nominal value. It is always charged in Sui.

  • Swap: This fee is collected on every swap and is defined in percentage. It is taken both in Sui and the meme coin.

  • Migration: This fee is charged in Sui from the liquidity being migrated in percentage.

  • Allocation: This fee is charged in meme coin after migration in percentage.

Recrd Configuration

The Recrd fees configuration has 4 recipients and creation, swap, migration and allocation fees.

The other two recipients are set by the system. They are the Recrd and IPX treasury.

Recrd charges a frontend fee of $10 USD in Sui. ⅔ of the fee is sent to Recrd while the remaining is for IPX. IPX Treasury: 0xdd224f2287f0b38693555c6077abe85fcb4aa13e355ad54bc167611896b007e6

Nexa Configuration

The Nexa fees configuration has 2 system addresses to be charged on the migration and swap fee.

Nexa supports custom configuration option per pool. This means the caller can select the following parameters for their pump pools:

  • Burn Tax (BPS)

  • Virtual Liquidity

  • Target Quote Liquidity

  • Liquidity Provision (BPS)

Nexa charges a front end Swap fee

The fees configuration can be fetched via the SDK using the following.

At pool creation, the caller can pass an to set dynamic fee recipients. This has to match the number of fees distribution set by the integrator. For example: if the integrator sets the creation fee to be 2 Sui and have 3 recipients and one recipient to always be the system. The pool creator must pass two additional addresses dynamically.

Two recipients are dynamically set at pool creation by passing their addresses .

Creation
Swap
Migration
Allocation
Creation
Swap
Migration
Allocation
const stakeHolders = [VIDEO_CREATOR_ADDRESS, TOKEN_CREATOR_ADDRESS];

0 Sui

1 %

5%

3%

25% Token Creator

25% Token Creator

33% Token Creator

25% Video Creator

25% Video Creator

33% Video Creator

50% Recrd

40% Recrd

33% Recrd

10 % IPX

0 Sui

0.25%

0.5%

0%

100% IPX

60% Nexa

40% IPX

method
array of stakeholders (Sui addresses)
here

Bonding Curve

The pump and auction strategies utilize the constant product invariant popularized by UniswapV2. The stable strategy utilizes a fixed rate to provide a no loss bonding curve.

Constant Product

  • k = constant

  • x = Reserves of Coin X

  • y = Reserves of Coin Y

This formula defines the pricing relationship between Coin X and Coin Y in a pool.

Pricing Function

X’ * Y’ = K

X’ = X + amountIn

Y’ = Y - amountOut

X * Y = (X + amountIn) * (Y - amountOut)

XY / (X + amountIn) = Y - amountOut

XY / (X + amountIn) - Y = -amountOut

XY / (X + amountIn) - Y (X + amountIn) / (X + amountIn) = - amountOut

- Y *amountIn / (X + amountIn) = - amountOut

We conclude that amountOut in Y is defined by

After every mutation, we ensure that the pool always maintains the invariant k = x * y by using the pricing formula above.

Virtual Liquidity

The use of virtual liquidity to create a floor price for the meme coin brings two benefits:

  • Allows the token creator to start a market without supplying any Sui liquidity

  • Prevents early buyers from getting too much supply.

Let us assume a pool of Meme/Sui. All pools on Memez.Fun use the Meme coin as the base coin and Sui as the quote coin. For example, let's imagine the absence of fees and first buy from the coin creator. If we would set up a pool with 1 billion coins of Meme and 0 Sui, we would break the invariant as k = 1e9 * 0.

This means that the pool would always be worth 0. To circumvent this issue, UniV2 forces the user to always supply both coins: the base coin and the quote coin. This is where virtual liquidity comes in, we can virtually set the pool with a floor price without requiring any investment from the token creator.

For example, We can set the virtual liquidity to be 1,000 Sui. If we assume that Sui is 5 dollars for simplicity sake, this means that at pool creation. The pool would be worth 10 thousand USD:

  • 5 Thousand worth of Sui

  • 5 Thousand worth of Meme

Assume we create Meme coin with 1e9 supply. 1 Meme coin would be worth 0.000001 Sui or ~$0.000005 (assuming Sui is $5).

Memez.Fun has a target Sui reserve that once it is achieved, the pool is migrated to a DEX.

Let's assume that we want the pool to migrate once the Meme achieves a market cap of $60,000.

Pool at start:

  • Virtual Liquidity: 1,000 Sui

  • Sui Reserves: 0

  • Meme Reserves: 1e9

  • Target Sui Reserve: 2,464 Sui

  • Meme Coin price: 0.000001 Sui

  • Target Meme Coin price: 0.000012 SUI

  • Pool Value: $0

  • Pool Virtual Value: $10,000

Target Meme Coin price explanation:

$60_000 / 1e9 Meme coin = $0.00006 per Meme

In Sui: $0.00006/$5 = 0.000012 SUI per Meme

0.000012 SUI per Meme Coin * 1e9 Meme Coin = 12,000 Sui ~ ($60,000)

How do we come up with a target Sui Reserve of 2,464 Sui?

  • Target Price = 0.000012 Sui

  • k = x * y = 1e12 (1e9 * 1000)

x * (0.000012x) = 1e12

0.000012x² = 1e12

x = sqrt(1e12/0.000012) ≈ 288,675,135 Meme tokens

Final y = 1e12/288,675,135 ≈ 3,464 Sui

Sui needed = 3,464 - 1,000 = 2,464 Sui

Conclusion: We would need a total of $12,321 (2,464 Sui) to migrate.

If we use the pricing formula above, we can see that it holds true:

(1e9 Meme * 2,464 Sui) / (1,000 Sui + 2,464 Sui) = 711,316,397 Meme

1e9 - 711,316,397 = 288,683,603

The pool would have 288,683,603 Meme and 3,464 Sui after a 2,464 Sui purchase. Using the price formula.

Price = y / x

3,464 Sui / 288,683,603 Meme ~ 0.000012

0.000012 * 1e9 = 12,000 Sui ($60,000)

Pool at the end:

  • Virtual Liquidity: 1,000 Sui

  • Sui Reserves: 2,464

  • Meme Reserves: 288,683,603

  • Target Sui Reserve: 2,464 Sui

  • Meme Coin price: 0.000012 Sui

  • Target Meme Coin price: 0.000012 Sui

  • Pool Value: $12,320

  • Pool Virtual Value: $17,320

k=x∗yk = x * yk=x∗y
Y∗amountIn/X+amountInY * amountIn / X + amountInY∗amountIn/X+amountIn
Price=y/xMemePrice=SuiReserve/MemeReservePrice = y / x\\MemePrice = Sui Reserve / Meme Reserve Price=y/xMemePrice=SuiReserve/MemeReserve

Configuration

Overview

Memez.gg is highly configurable to facilitate third party integrations and revenue sharing.

Integrators can configure the following parameters:

  • Burner tax

  • Fees

  • Pump Configuration

  • Auction Configuration

  • Stable Configuration

During creation, the deployer can choose which configuration the pool will adhere to. E.g., user A could opt for the Default configuration, while user B opts for another.

Integrators need to request our team to add their configuration.

Burner

The Auction and Pump strategies have a burn tax built-in. This is a dynamic tax that increases linearly as the amount of Sui in the pool increases. It can range from 0 to 30%. This tax is only applied when one sells Meme coins for Sui. The coins are actually burnt (not sent to 0x0) as Memez uses the IPX Coin Standard for all meme coins. This is to prevent king of the hill griefing tactics. As the tax is quite high when it is close to bonding.

public struct MemezBurner has copy, drop, store {
    fee: BPS,
    target_liquidity: u64,
}
  • Fee: A percentage in bps to determine how much amount to burn.

  • Target Liquidity: The liquidity required t migrate the pool.

Example

Burner tar Tax Formula

progress = current_liquidity / target_liquidity

tax = burner_tax * progress Example

Let's assume we have a pool using the Pump strategy with a Sui Target Amount of 1_000 Sui and a Burner tax of 20% of 2_000 basis points.

t0: The pool has 0 Sui - burn tax would be 0%

Math:

progress = 0 / 1_000 ⇒ 0

20% * 0 / 1000 ⇒ 0%

t1: The pool has 800 Sui - burn tax would be 16%

Math:

progress = 800 / 1_000 ⇒ 80%

20% * 80% ⇒ 16%

Fees

Memez.fun has 3 fees:

public struct FeePayload has copy, drop, store {
    value: u64,
    percentages: vector<u64>,
    recipients: vector<address>,
}

public struct Allocation<phantom T> has store {
    balance: Balance<T>,
    vesting_period: u64,
    distributor: Distributor,
}

public struct MemezFees has copy, drop, store {
    creation: FeePayload,
    swap: FeePayload,
    migration: FeePayload,
    allocation: FeePayload,
    vesting_period: u64,
}
  • Creation: Sui amount charged to create a meme coin + pool.

  • Swap: % charged on every sell or buy.

  • Migration: Meme coin % to be used for DEX liquidity after migration.

  • Allocation: Meme coin % allocated for the stake holders.

  • Vesting Period: The duration of the linear vesting for the allocation.

The integrator can decide the total amount of each fee and the number of recipients per fee. It is possible to charge no fees at all and different percentages and recipients per fee. The swap and migration fee include the deployer as one of the recipients if chosen by the integrator.

For example an integrator can decide to have:

  • Creation Fee of 2 Sui:

    • 20% to X

    • 60% to Y

    • 20% to Z

  • No Swap fee

  • 10 % Migration quote fee

    • 50% to A

    • 50% to B

  • 5% Meme coin allocation to stake holders

Pump Configuration

The pump strategy has 4 configurable parameters:

public struct PumpConfig has copy, drop, store {
    burn_tax: u64,
    virtual_liquidity: u64,
    target_quote_liquidity: u64,
    liquidity_provision: BPS,
    quote_type: TypeName,
}
  • Burn Tax: The burner tax explained above

  • Virtual Liquidity: The floor price of the Meme coin as determined by a virtual Sui amount

  • Target Sui Liquidity: The amount of Sui the pool must collect to migrate. It can be seen as a target price.

  • Liquidity Provision: Percentage of Meme coin to be used to seed the liquidity pool during migration.

  • Quote Type: The type of the quote Coin<Quote>.

Auction Configuration

The pump strategy has 7 configurable parameters:

public struct AuctionConfig has copy, drop, store {
    auction_duration: u64,
    target_quote_liquidity: u64,
    liquidity_provision: BPS,
    seed_liquidity: BPS,
    quote_type: TypeName
}
  • Auction Duration: How long should the auction last.

  • Target Quote Liquidity: The amount of Sui the pool must collect to migrate. It can be seen as a target price.

  • Liquidity Provision: Percentage of Meme coin to be used to seed the liquidity pool during migration.

  • Seed Liquidity: Percentage of meme coin that the pool should start with at the beginning of the auction.

  • Quote Type: The type of the quote Coin<Quote>.

Stable Configuration

The pump strategy has 3 configurable parameters:

public struct StableModel has copy, drop, store {
    max_target_sui_liquidity: u64,
    liquidity_provision: BPS,
    meme_sale_amount: BPS,
    quote_type: TypeName
}
  • Max Target Sui Liquidity: The maximum amount of liquidity the deployer can raise.

  • Liquidity Provision: Percentage of Meme coin to be used to seed the liquidity pool during migration.

  • Meme Sale Amount: Percentage of Meme coin to sell during the bonding phase.

  • Quote Type: The type of the quote Coin<Quote>.

Move Dependencies

Interest BPS

It is an utility library to calculate percentages from values using basis points. It is referred as BPSin the code blocks.

IPX Coin Standard

It is an utility library designed to separate the capabilities of the treasury cap (mint/burn/update) to provide the owner more granular control.

Interest Math

A math library to safely perform operations.

Constant Product

A library that calculates the amount in and out of the constant product formula k = x * y

IPX Coin Standard

An extension to Sui Network's Coin. Coins created via the IPX Coin Standard can be minted, burnt and updated with different capabilities.

Problem

Coins created via Sui Network Coin have all the rights associated with one capability, the TreasuryCap.

The holder of the TreasuryCap can mint, burn and update the Coin. This design is quite limiting because all the rights are associated with a single capability.

What happens if a user wants to ensure that its coin can be burnt but not mintable? He would have to write its own contract.

Most users choose to simply send the TreasuryCap to the systems address, the famous 0x0, because no one has access to it. Therefore it is considered burnt. However, since no one has access to the TreasuryCap, no one can burn the coin nor update its icon, description, symbol or name. There are cases in which coins need to update its metadata due to a rebrand or broken uris.

Solution

The IPX Coin Standard separates the three rights of the TreasuryCap into three separate capabilities: Burn, Mint and Update metadata. This flexible design means that a user can make his/her coin burnable while preventing coins to be minted forever.

  • MintCap allows the holder to mint coins

  • BurnCap allows the holder to burn coins

  • MetadataCap allows the holder to update the coin name, description, icon uri and symbol

The deployer can choose to make the coin burnable by anyone who has coins in his/her wallet.

Mainnet Package Address: 0xa204bd0d48d49fc7b8b05c8ef3f3ae63d1b22d157526a88b91391b41e6053157 Testnet Package Address: 0x3d9d9cf7f37daa21d6439bb4f3e90b49312cc1471e159e0b34ef18a36332ccda

MVR

Interest Protocol Decentralized Exchange (DEX)

Welcome to Interest Protocol DEX, a versatile decentralized exchange built on the Movement Network. The platform is designed for seamless trading, advanced liquidity management, and effortless token creation, all while incorporating cutting-edge security features to protect users from common exploits like sandwich attacks.

Get Started

  1. Swap Tokens: Trade safely with built-in protections.

  2. Manage Liquidity: Provide liquidity with ease using dynamic tools.

  3. Create Tokens: Launch and deploy liquidity pools effortlessly.


Interest Protocol DEX is your gateway to secure, efficient, and innovative DeFi trading. Dive in today and explore its powerful tools to transform your crypto journey!

Pump API

Constructor

Allows the SDK to be initiated with custom data.

How to use:

Arguments

  • fullNodeUrl {string} - Url to initiate the Sui Client RPC

newPumpPool

Creates a pool using the Pump invariant.

How to use:

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • creationSuiFee {object} - The Sui fee to create a MemezPool.

  • memeCoinTreasuryCap {string} - The meme coin treasury cap.

  • totalSupply {string | number | bigint} - The total supply of the meme coin.

  • useTokenStandard {boolean} - Whether to use the token standard for the MemezPool.

  • devPurchaseData {object} - An object containing the quote Coin to to perform the first buy tx and the address of the person who can claim the coins.

  • metadata {object} - A record of the social metadata of the meme coin.

  • configurationKey {string} - The configuration key to use for the MemezPool.

  • migrationWitness {string} - The migration witness to use for the MemezPool.

  • stakeholders {string[]} - The addresses of the stakeholders. It can be empty or undefined.

  • quoteCoinType {string} - The quote coin type to use for the MemezPool.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • metadataCap {object} - The metadata object.

pump

Swaps quote coin for a meme coin in a pool.

The swap fee is taken from the coin being sold. In this case Quote.

How to use

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

  • quoteCoin {object} - The quote coin to sell for the meme coin.

  • minAmountOut {string | number | bigint} - The minimum amount of meme coin expected to be received.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • memeCoin {object} - The meme coin bought.

dump

Swaps meme coin for quote coin in a pool.

The swap fee is taken from the coin being sold. In this case the Meme coin.

How to use

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

  • memeCoin {object} - The meme coin to sell for Sui coin.

  • minAmountOut {string | number | bigint} - The minimum amount of sui coin expected to be received.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • quoteCoin {object} - The Quote coin bought.

pumpToken

Swaps quote coin for the meme token using the Token Standard.

This is for pools created with the token standard.

The swap fee is taken from the coin being sold. In this case Quote.

How to use

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

  • quoteCoin {object} - The Sui coin to sell for the meme coin.

  • minAmountOut {string | number | bigint} - The minimum amount meme coin expected to be received.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • memeToken {object} - The meme token bought.

  • memeCoinType {string} - The type of the meme coin.

dumpToken

Swaps the meme token for quote coin.

This is for pools created with the token standard.

The swap fee is taken from the coin being sold. In this case the Meme coin.

How to use

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

  • memeToken {object} - The meme token to sell for Sui coin.

  • minAmountOut {string | number | bigint} - The minimum amount sui coin expected to be received.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • quoteCoin {object} - The quote coin bought.

devClaim

Allows the developer to claim the first purchased coins. It can only be done after the pool migrates.

How to use

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • memeCoin {object} - The meme coin bought by the developer during deployment.

keepToken

Utility function to return the Token to the sender.

How to use

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • token {string | object} - The objectId of the meme token to keep.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • memeCoin {object} - The meme coin bought by the developer during deployment.

toCoin

Converts a meme token to a meme coin. This is for pools that use the Token Standard. It can only be done after the pool migrates.

How to use

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

  • memeToken {object} - The meme token to convert to a meme coin.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • memeCoin {object} - The meme coin converted from token.

migrate

Migrates the pool to DEX based on the MigrationWitness.

How to use

Arguments

  • tx {object} - Sui client Transaction class to chain move calls.

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

Return

  • tx {object} - Sui client Transaction class to chain move calls.

  • migrator {object} - The hot potato migrator containing the balances.

quotePump

Quotes the amount of meme coin received after selling the quote coin.

The swap fee is taken from the coin in. In this case Sui.

How to use

Arguments

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

  • amount {string | number | bigint} - The amount of Sui being sold.

Return

  • memeAmountOut {bigint} - The amount of meme coin that will be received.

  • swapFeeIn {bigint} - The swap fee paid in Sui.

quoteDump

Quotes the amount of quote coin received after selling the meme coin.

The swap fee is taken from the coin in. In this case, the meme coin.

How to use

Arguments

  • pool {string | object} - The objectId of the MemezPool or the full parsed pool.

  • amount {string | number | bigint} - The amount of Mem coin being sold.

Return

  • quoteAmountOut {bigint} - The amount of quote coin that will be received.

  • swapFeeIn {bigint} - The swap fee paid in Meme coin.

  • burnFee {bigint} - Burn fee in meme coin.

getPumpData

Returns the Pump configuration for a specific integrator using a configuration key.

How to use

Arguments

  • configurationKey {string} - The struct tag of a configuration key. E.g. package::module::Key

  • totalSupply {string | bigint | number} - The total supply of the meme coin. E.g. 1 Sui would be 1e9.

Return

  • burnTax - The tax value of the burner in bps.

  • virtualLiquidity - The starting virtual liquidity in the pool in Sui.

  • targetQuoteLiquidity - The amount of quote required for the pool to migrate.

  • liquidityProvision - The amount of Meme coin that will be supplied to a DEX after migration.

Key Features

1. Token Swap

The Swap Tool allows users to exchange tokens directly in a simple and intuitive interface. With built-in protection against sandwich attacks, Interest Protocol ensures users can trade safely without the risk of bots exploiting their transactions.

Example: How to Swap Tokens

  • Select the tokens you want to swap (e.g., MOVE → RUCO).

  • Enter the desired amount and confirm the transaction.

  • The DEX processes your swap securely with price stability thanks to its slot windows, which mitigate sandwich attacks.

Swap Tutorial

This feature ensures smooth transactions, even in volatile markets, with no extra steps required from the user.


2. Advanced Liquidity Management

Interest Protocol introduces a robust liquidity layer where projects and users can manage pools effortlessly. This feature supports both passive liquidity provision and innovative functionalities for liquidity providers (LPs):

  • One-Sided Liquidity: LPs can provide liquidity with a single token, eliminating the need for equal-value pairs.

  • Dynamic Liquidity Adjustment: The protocol automatically adjusts liquidity positions, reducing impermanent loss and enhancing fee capture for LPs.

  • Multi-Coin Pools: Pools can include more than two assets, enabling creative and efficient trading pairs.

  • LpCoins: Unlike traditional NFTs for liquidity, LpCoins are fungible, composable, and easily tradable, enhancing their usability within DeFi ecosystems.


3. Create and Launch Tokens

The Token Launcher is a powerful tool that allows anyone to create and launch new tokens without requiring coding skills. Along with token creation, users can seamlessly deploy liquidity pools to support their tokens.

Steps to Create and Launch a Token

  1. Fill in token details:

    • Name, Symbol, Description, and upload a Logo.

  2. Set the Total Supply.

  3. Choose to deploy a liquidity pool during the creation process.

  4. Specify the amount of liquidity to add for your token’s pool.

  5. Confirm the transaction, and your token is live, backed by a liquidity pool.

This feature empowers developers and community members to bring new tokens to market efficiently and securely, fostering innovation in the DeFi space.

At deployment the user can choose to make the coin mintable, burnable and/or updateable and decide who has those rights. The code is open source on and . Not even the IPX team can change the standard making it safe to use.

IPX Coin standard is available on .

Visit the Platform:

network {Enum} -

packages {Object} -

sharedObjects {object} -

I

I

E

Imp

The migrator is a hot potato that needs to be consumed. Please use the to consume and migrate to a DEX. At the moment, we only have a test migrator as Memez is deployed on testnet.

Visit .

Navigate to the page.

mvr add @interest/coin-standard --network mainnet
import { getFullnodeUrl } from '@mysten/sui/client';
import {
  MemezPumpSDK,
  MemezStableSDK,
  PACKAGES,
  SHARED_OBJECTS,
  Network,
} from '@interest-protocol/memez-fun-sdk';

// Default settings (Testnet)
const memezPumpTestnet = new MemezPumpSDK();

// Default settings (Testnet)
const memezStableTestnet = new MemezStableSDK();

// Custom setup
const memezPump = new MemezPumpSDK({
  fullNodeUrl: getFullnodeUrl('mainnet'),
  network: Network.Mainnet,
  packages: PACKAGES[Network.Mainnet],
  sharedObjects: SHARED_OBJECTS[Network.Mainnet],
});
  const recipient = keypair.toSuiAddress();

  const tx = new Transaction();

  const [creationSuiFee, devPurchase] = tx.splitCoins(tx.gas, [
    tx.pure.u64(30_000_000n),
    tx.pure.u64(1_000_000_000n),
  ]);

  const { metadataCap } = await memezPumpTestnet.newPool({
    tx,
    configurationKey,
    metadata: {
      X: 'https://x.com/Meme',
      Website: 'https://meme.xyz/',
      GitHub: 'https://github.com/meme',
      videoUrl: 'https://memez.gg',
    },
    creationSuiFee,
    memeCoinTreasuryCap: TREASURY_CAP,
    devPurchaseData: {
      developer: recipient,
      firstPurchase: devPurchase,
    },
    migrationWitness: MIGRATOR_WITNESSES.testnet.TEST,
    totalSupply: TOTAL_SUPPLY,
    useTokenStandard: true,
    quoteCoinType: SUI_TYPE_ARG,
  });
  tx.transferObjects([metadataCap], tx.pure.address(recipient));

  await executeTx(tx);
const tx = new Transaction();

const suiCoin = tx.splitCoins(tx.gas, [tx.pure.u64(103n * POW_9)]);

const { memeCoin, tx: tx2 } = await memezPumpTestnet.pump({
  pool: TEST_POOL_ID,
  quoteCoin,
  tx,
});

tx2.transferObjects([memeCoin], keypair.toSuiAddress());

await executeTx(tx2);
const tx = new Transaction();

const pool = await memezTestnet.getPumpPool(TEST_POOL_ID);

const memeCoin = await getCoinOfValue({
  tx,
  coinType: pool.memeCoinType,
  coinValue: 990500n * 10n,
});

const { quoteCoin, tx: tx2 } = await memezPumpTestnet.dump({
  pool: TEST_POOL_ID,
  memeCoin,
  tx,
});

tx2.transferObjects([quoteCoin], keypair.toSuiAddress());

await executeTx(tx2);
const tx = new Transaction();

const quoteCoin = tx.splitCoins(tx.gas, [tx.pure.u64(105n * POW_9)]);

const { memeToken, tx: tx2 } = await memezPumpTestnet.pumpToken({
  pool: TEST_POOL_ID,
  quoteCoin,
  tx,
});

const { tx: tx3 } = await memezPumpTestnet.keepToken({
  memeCoinType: MEME_COIN_TYPE,
  token: memeToken,
  tx: tx2,
});

await executeTx(tx3);
const tx = new Transaction();

const { quoteCoin, tx: tx2 } = await memezPumpTestnet.dumpToken({
  pool: TEST_POOL_ID,
  memeToken:
      '0x0a256522091a350e3cc3ac86982608803bce754ede1199785227bfc822603b71',
  tx,
});

tx2.transferObjects([quoteCoin], tx.pure.address(keypair.toSuiAddress()));

await executeTx(tx2);
const { memeCoin, tx } = await memezTestnet.devClaim({
  pool: TEST_POOL_ID,
});

tx.transferObjects([memeCoin], keypair.toSuiAddress());

await executeTx(tx);
const { tx: tx3 } = await memezPumpTestnet.keepToken({
  memeCoinType: MEME_COIN_TYPE,
  token: memeToken,
  tx: tx2,
});
const { memeCoin, tx } = await memezPumpTestnet.toCoin({
  pool: TEST_POOL_ID,
  memeToken: TOKEN_ID,
});

tx.transferObjects([memeCoin], tx.pure.address(keypair.toSuiAddress()));

await executeTx(tx);
const { tx, migrator } = await memezPumpTestnet.migrate({
  pool: TEST_POOL_ID,
});

const migratorSDK = new MigratorSDK();

const { tx: tx2 } = migratorSDK.migrate({
  tx,
  migrator,
  memeCoinType: MEME_COIN_TYPE,
});

await executeTx(tx2);
import { memezTestnet, POW_9, TEST_POOL_ID } from '../utils.script';

const { memeAmountOut, swapFeeIn } = await memezPumpTestnet.quotePump({
  pool: TEST_POOL_ID,
  amount: 15n * POW_9,
});
  
console.log({ memeAmountOut, swapInFee });
import { memezTestnet, POW_9, TEST_POOL_ID } from '../utils.script';


const { amountOut, swapFeeIn, burnFee } = await memezPumpTestnet.quoteDump({
  pool: TEST_POOL_ID,
  amount: 1_500_000n * POW_9,
});

console.log({ amountOut, swapFeeIn, burnFee });
import { CONFIG_KEYS } from '../../memez';
import { log, memezTestnet } from '../utils.script';


const pumpData = await memezPumpTestnet.getPumpData({
    configurationKey: CONFIG_KEYS.testnet.DEFAULT,
    totalSupply: 1e9 * 1e9,
    quoteCoinType: QUOTE_COIN_TYPE
 });

log(pumpData);
Github
immutable
Move Registry
Interest Protocol DEX
Example
Pump SDK Implementation
Stable SDK Implementation
Enum denoting if its mainnet or testnet
Record of the deployed Memezfun packages on mainnet and testnet
Record of the shared object ids on mainnet and testnet
Example
mplementation
Check out the IPX Treasury standard
Example
Implementation
Example
mplementation
Example
Implementation
Example
Implementation
Example
Implementation
xample
Implementation
Example
lementation
Example
Implementation
Migrator SDK
Example
Implementation
Example
Implementation
Example
Implementation
Interest Protocol DEX
Create Token

Core Innovations

Sandwich Attack Prevention

Interest Protocol protects users from sandwich attacks by introducing slot windows where the bid price remains constant during transactions. This innovative approach discourages malicious bots by making such attacks unprofitable.

Stable Curve

The protocol uses a hybrid bonding curve for correlated assets, combining:

  • Constant Product Invariant: Ensures balanced liquidity.

  • Constant Sum Invariant: Amplifies liquidity around the mid-range for optimal pricing.

Volatile Curve

For volatile assets, the platform tracks prices with an internal exponential moving average (EMA), concentrating liquidity around the current market price to enhance trading efficiency.

Hooks for Customization

Inspired by Uniswap V4, hooks enable deployers to customize pools with advanced features such as:

  • Pre-swap/post-swap computations.

  • Fee-on-swap models.

  • Custom oracles or limit orders.

Security

DeFi has justly been criticized for its subpar security standards. Last year, we saw a 300 million USD hack on Solana wormhole. Security is a constant battle, and there is no single solution for it. We will always prioritize security over features or development speed.

We will employ the following security measures to fight hacks:

  • 100% unit test coverage

  • Formal verification tools once Move prover is updated

  • Working MVP on a test-net before deployment

  • Security audits before every deployment

  • Upgradeable contracts to fix bugs post-deployment

  • Bug bounties

  • Secure oracles with backups

  • Time locks to protect users from future changes

  • Multi-signature wallets

We are Open-source

Open source platforms like Interest Protocol promote transparency and builds trust, encourages collaboration and innovation. We are accessible to users even those with limited resources. We feel secure because our vulnerabilities can be identified and fixed faster.

Coin X Oracle 🔮

Purpose

Coin X Oracle allows developers to easily deploy price oracles from various feeds without having to worry about each provider's intricacies and interfaces.

Upon requesting a price update, the Coin X Oracle will collect the price from various feeds and run a set of checks to make sure of its liveness and accuracy.

Flow

  1. Request a price update

  2. Collect the data from predetermined providers.

  3. Run a set of checks to ensure the price accuracy and liveness.

Security

The entire process from the data request to reading it inside a DeFi dApp happens in one transaction block atomically through the use of hot potatoes. Price consumers have 100% confidence in the liveness and accuracy of the data.

Feeds

The following feeds are available:

  • Pyth Network

  • Switchboard

Refer to the SuiTears💧interface documentation to learn Coin X Oracle's interface.

sr-AMM

Sandwich Resistant Automated Market Maker

What is sandwich attacks and why should I care?

"Just let me ape" - everyday degenerate

AMMs are the primarly venue for meme coin trading and users tend to use high slippage to guarantee early entries. What most do not realize is that this exposes them to sandwich bots. This is a major issue that, for reference 50K Solana was essentially stolen in 1 month in 2024 due to this. The way is works is that Bots can see your transaction on the meme pool and simply place one to buy beforehand and another to sell right after. The first transaction increases the price, the user then purchases at a higher price increasing it further and then the bot sells at a profit.

Fine, what do I do?

Glad you ask, all you have to do is trade on Interest Protocol! Our AMM prevents most of the sandwich bot attacks by introducing slot windows in which the bid price is constant. In simpler terms, if a bot sandwiches you, it will lose money. There are no extra steps needed for the users, it is an invisible solution to the application layer.

For further reading check out this article.

Deprecated

This is code that is pending to change and is not longer recommended to be used in production.

Switchboard

Why Switchboard ?

Switchboard provides a trusted execution environment to ensure off-chain oracles are not tempered with.It also allows for developers to deploy custom oracles.

Interface

Structs

struct AggregatorKey has copy, drop, store {}

A dynamic field key to store the address of the switchboard::aggregator::Aggregator that can that provide data to the oracle.

 struct SwitchboardFeed has drop {}

A witness that is added to the suitears::oracle::Request to prove that it collected data from Coin X Oracle's Pyth Network module.

Functions

report

It requests a price from Pyth Network and submits the information to a Coin X oracle request.

public fun report<Witness: drop>(oracle: &Oracle<Witness>, request: &mut Request, aggregator: &Aggregator)
  • @param self. A suiterars::oracle::Oracle with this module's witness.

  • @param request. A hot potato issued from the self to create a suiterars::oracle::Price.

  • @param aggregator. switchboard::aggregator::Aggregator that the self will use to fetch the price.

Aborts

  • the aggregator is not whitelisted.

  • the aggregator price is negative or zero.

Pyth Network

Reliable, low-latency market data from institutional sources.

Why Pyth?

The first price provider supported by Coin X Oracle is Pyth Network. It is the leading Oracle provider on Sui Network and the largest first-party Oracle Network in the world. It supports of over 50 chains and offers 450 price feeds.

First Party Institutional Providers

Pyth network data sources do not rely on intermediaries to ensure reliability and liveness of the data.

Price Confidence

Pyth Network is the only provider that offers a price confidence metric in all price feeds. Assets do not have a single price in a market at any given point in time. By providing a confidence range, DeFi dApps can design their invariant to take into account price variance.

Interface

Structs

struct PriceInfoObjectKey has copy, drop, store {}

A dynamic field key to store the sui::object::ID of the pyth::price_info::PriceInfoObject that can that provide data to the oracle.

struct ConfidenceKey has copy, drop, store {}

A dynamic field key to save the minimum required price confidence. It is a percentage, where 100% is represented by 1e18.

struct PythFeed has drop {}

A witness that is added to the suitears::oracle::Request to prove that it collected data from Coin X Oracle's Pyth Network module.

Functions

report

It requests a price from Pyth Network and submits the information to a Coin X oracle request.

public fun report<Witness: drop>(
    oracle: &Oracle<Witness>, 
    request: &mut Request, 
    wormhole_state: &WormholeState,
    pyth_state: &PythState,
    buf: vector<u8>,
    price_info_object: &mut PriceInfoObject,
    pyth_fee: Coin<SUI>,
    clock_object: &Clock
 )
  • @param self. A suiterars::oracle::Oracle with this module's witness.

  • @param request. A hot potato issued from the self to create a suiterars::oracle::Price.

  • @param wormhole_state. The state of the Wormhole module on Sui.

  • @param pyth_state. The state of the Pyth module on Sui.

  • @param buf. Price attestations in bytes.

  • @param price_info_object. An object that contains price information. One per asset.

  • @param pyth_fee. There is a cost to request a price update from Pyth.

  • @param clock_object. The shared Clock object from Sui

Aborts

  • the price_info_object is not whitelisted.

  • the price confidence is out of range.

  • the price is negative or zero.

Audits

interest.xyz Aptos Move CLAMM

613KB
Interest Aptos CLAMM.pdf
pdf

Memez.gg launchpad

314KB
Memez.gg Audit Report.pdf
pdf

interest.xyz Movement Dynamic-Peg + Stable DEX

364KB
Interest Protocol Audit Report.pdf
pdf

interestprotocol.com Sui Dynamic-Peg + Stable DEX

654KB
Interest Protocol Audit Report.pdf
pdf

https://www.winterwalrus.com LST

350KB
Blizzard Audit Report.pdf
pdf

Airdrop Utils

Airdrop utils module contains the verify function to check if a Merkle proof combined with an address and amount are part of the Merkle tree root.

verify

Checks if the sender is allowed to redeem an amount from an airdrop using Merkle proofs. It returns the index of his Merkle proof to add to the Bitmap struct.

public fun verify(
    root: vector<u8>,
    proof: vector<vector<u8>>, 
    amount: u64, 
    sender: address
): u256
  • @param root: The Merkle tree root that keeps track of all the airdrops.

  • @param proof: The proof that the sender can redeem the amount from the airdrop.

  • @param amount: The airdrop amount.

  • @param sender: The address of the airdrop user.

  • @return u256. An index.

Aborts

  • if the leaf or proof are invalid.

Sui Tears 💧

is an open source production ready Sui Move library to increase the productivity of new and experienced developers alike.

- Verify function for the airdrop modules.

- A pull design airdrop to distribute tokens after a specific date.

- A pull design airdrop to distribute tokens according to a linear vesting schedule.

- Owner capability to give access to multiple objects.

- A wrapper that can only be unwrapped once a set of actions are completed.

- A wrapper that can only be unwrapped after a set timestamp.

- Capability access wrapper for collections.

- Bitmap implementation for sequential keys.

- A Collection that stores coin decimals.

- Witness access wrapper for collections.

- Module to reward coin stakers over time.

- Struct to track shares associated with underlying deposits/withdrawals.

- Wallet that distributes tokens according to a linear vesting schedule.

- Wallet that distributes tokens according to a linear vesting schedule and allows the owner to reclaim the locked coins.

- Virtual implementation of vesting schedules

- Decentralized autonomous organization

- The admin capability for DAOs

- Treasury plugin for DAOs

- Fixed point math module for numbers scaled to x << 64.

- Fixed point math module for numbers with 1e9 precision.

- Fixed point math for module for numbers with 1e18 decimals.

- Utility math functions for u64 numbers.

- Utility math functions for u128 numbers.

- Utility math functions for u256 numbers.

- Module to handle signed integer operations.

- Module to compare u8 vectors (bits).

- Module to verify Merkle proofs.

- A set of functions to operate on ASCII strings.

- Utility functions for vectors.

Sui Tears
Airdrop
Airdrop Utils
Airdrop
Linear Vesting Airdrop
Capabilities
Owner
Quest
Time Lock
Collections
Access Collection
BitMap
Coin Decimals
Witness Collection
DeFi
Farm
Fund
Linear Vesting Wallet
Linear Vesting Clawback Wallet
Vesting
Governance
Dao
Dao Admin
Dao Treasury
Math
Fixed Point 64
Fixed Point Roll
Fixed Point Wad
Math64
Math128
Math256
Int
Utils
Comparator
Merkle Proof
ASCII Utils
Vectors

Airdrop

Sui Tears💧 Airdrop modules are "pulled" based. The modules store the root of a Merkle tree that consists of the address of the user and the airdrop amount. Users are required to submit a Merkle proof to claim their airdrops. The leafs are constructed by hashing (sha3256) the sender's address concatenated with the amount.

Please check here on how to construct the Merkle Tree.

Structs

Airdrop

struct Airdrop<phantom T> has key, store { 
    id: UID,
    balance: Balance<T>,
    root: vector<u8>,
    start: u64, 
    map: Bitmap
}
  • balance - Coins to airdrop

  • root - The root of the Merkle tree

  • start - The timestamp in which users can claim the airdrop

  • map - Bitmap keeps track of airdrop claims.

Interface

new

It creates the Airdrop object.

public fun new(airdrop_coin: Coin<T>, root: vector<u8>, start: u64, c: &Clock, ctx: &mut TxContext): Airdrop<T>
  • @param airdrop_coin: The coin that will be distributed in the airdrop.

  • @param root: The Merkle tree root that keeps track of all the airdrops.

  • @param start: The start timestamp of the airdrop in milliseconds.

  • @param c: The sui::clock::Clock shared object.

  • @return Airdrop<T>

Aborts

  • root is empty.

  • start time of the airdrop is in the past.

balance

Returns the current amount of airdrop coins in the Airdrop object.

public fun balance<T>(self: &Airdrop<T>): u64
  • @param: self The shared Airdrop object

  • @return u64

root

Returns the root of the Merkle tree for the airdrop.

public fun root<T>(self: &Airdrop<T>): vector<u8>
  • @param: self The shared Airdrop object.

  • @return vector<u8>.

start

Returns the start timestamp of the airdrop. Users can claim after this date.

public fun start<T>(self: &Airdrop<T>): u64
  • @param: self The shared Airdrop object.

  • @return u64.

borrow_map

Returns an immutable reference of the Bitmap. It keeps track of the claimed airdrops.

public fun borrow_map<T>(self: &Airdrop<T>): &Bitmap
  • @param: self The shared Airdrop object.

  • @return &Bitmap.

has_account_claimed

Checks if a user has already claimed his airdrop.

public fun has_account_claimed<T>(
    self: &Airdrop<T>, 
    proof: vector<vector<u8>>, 
    amount: u64, 
    user: address
  ): bool
  • @param self: The shared Airdrop object.

  • @param proof: The proof that the sender can redeem the amount from the airdrop.

  • @param amount: Number of coins the sender can redeem.

  • @param address: A user address.

  • @return bool. True if he has claimed the airdrop already.

Aborts

  • If the proof is not valid.

get_airdrop

Allows a user to claim his airdrop by proving that his address and amount are in the Merkle tree.

public fun get_airdrop<T>(
    self: &mut Airdrop<T>, 
    proof: vector<vector<u8>>, 
    c: &Clock,
    amount: u64, 
    ctx: &mut TxContext
): Coin<T>
  • @param self: The shared Airdrop object.

  • @param proof: The proof that the sender can redeem the amount from the airdrop.

  • @param c: The sui::clock::Clock shared object.

  • @param amount: Number of coins the sender can redeem.

  • @return Coin<T>. The airdrop Coin.

Aborts

  • If the proof is not valid.

  • The airdrop has not started yet.

  • The user already claimed it

destroy_zero

Destroys an empty Airdrop object.

public fun destroy_zero<T>(self: Airdrop<T>)
  • @param self: The shared {Airdrop} object.

Aborts

  • The self has left over coins.

Linear Vesting Airdrop

Sui Tears💧 Airdrop modules are "pulled" based. The modules store the root of a Merkle tree that consists of the address of the user and the airdrop amount. Users are required to submit a Merkle proof to claim their airdrops. The leafs are constructed by hashing (sha3256) the sender's address with the amount. This module returns the airdrop inside a linear vesting airdrop wallet.

Please check here on how to construct the Merkle Tree.

Structs

Airdrop

struct Airdrop<phantom T> has key, store { 
    id: UID,
    balance: Balance<T>,
    root: vector<u8>,
    start: u64, 
    duration: u64,
    map: Bitmap
}
  • balance - Coins to airdrop

  • root - The root of the Merkle tree

  • start - The timestamp in which the vesting schedule starts.

  • duration - The duration of the vesting schedule.

  • map - Bitmap keeps track of airdrop claims.

Interface

new

Creates a linear vested airdrop.

public fun new<T>(airdrop_coin: Coin<T>, root: vector<u8>, start: u64, duration: u64, c: &Clock, ctx: &mut TxContext): Airdrop<T>
  • @param airdrop_coin: The coin that will be distributed in the airdrop.

  • @param root: The Merkle tree root that keeps track of all the airdrops.

  • @param start: The start timestamp of the vesting schedule.

  • @param duration: The duration of the vesting schedule.

  • @param c: The sui::clock::Clock shared object.

  • @return Airdrop<T>

Aborts

  • root is empty.

  • start time of the airdrop is in the past.

balance

Returns the current amount of airdrop coins in the Airdrop object.

public fun balance<T>(self: &Airdrop<T>): u64
  • @param: self The shared Airdrop object

  • @return u64

root

Returns the root of the Merkle tree for the airdrop.

public fun root<T>(self: &Airdrop<T>): vector<u8>
  • @param: self The shared Airdrop object.

  • @return vector<u8>.

start

Returns the start timestamp of the airdrop. Users can claim after this date.

public fun start<T>(self: &Airdrop<T>): u64
  • @param: self The shared Airdrop object.

  • @return u64.

duration

Returns the duration of the vesting schedule.

public fun duration<T>(self: &Airdrop<T>): u64
  • @param: self The shared Airdrop object.

  • @return u64.

borrow_map

Returns an immutable reference of the Bitmap. It keeps track of the claimed airdrops.

public fun borrow_map<T>(self: &Airdrop<T>): &Bitmap
  • @param: self The shared Airdrop object.

  • @return &Bitmap.

has_account_claimed

Checks if a user has already claimed his airdrop.

public fun has_account_claimed<T>(
    self: &Airdrop<T>, 
    proof: vector<vector<u8>>, 
    amount: u64, 
    user: address
  ): bool
  • @param self: The shared Airdrop object.

  • @param proof: The proof that the sender can redeem the amount from the airdrop.

  • @param amount: Number of coins the sender can redeem.

  • @param address: A user address.

  • @return bool. True if he has claimed the airdrop already.

Aborts

  • If the proof is not valid.

get_airdrop

Allows a user to claim his airdrop by proving that his address and amount are in the Merkle tree.

  public fun get_airdrop<T>(
    self: &mut Airdrop<T>,
    proof: vector<vector<u8>>,  
    clock_object: &Clock,
    amount: u64, 
    ctx: &mut TxContext
  ): Wallet<T>
  • @param self: The shared Airdrop object.

  • @param proof: The proof that the sender can redeem the amount from the airdrop.

  • @param c: The sui::clock::Clock shared object.

  • @param amount: Number of coins the sender can redeem.

  • @return Wallet. The airdrop Coin locked in a linear vested {Wallet}.

Aborts

  • If the proof is not valid.

  • The user already claimed it

destroy_zero

Destroys an empty Airdrop.

public fun destroy_zero<T>(self: Airdrop<T>)
  • @param self: The shared {Airdrop} object.

Aborts

  • The self has left over coins.

Capabilities

Access Control

It allows an admin to manage access control via roles.

Structs

AccessControl

struct AccessControl has key, store {
 id: UID,
 roles: VecMap<vector<u8>, VecSet<address>>
}
  • roles - Map to store a role => set of addresses with said role.

Admin

struct Admin has key, store {
 id: UID,
 access_control: address
}
  • Address of the AccessControl this capability belongs to.

Interface

new

It creates an `AccessControl` and an `Admin` with the `SUPER_ADMIN_ROLE`.

public fun new(ctx: &mut TxContext): (AccessControl, Admin)
  • @return `AccessControl`. It stores the role's data.

  • @return `Admin`. The `SUPER_ADMIN_ROLE` `Admin`.

Quest

This module wraps an object labeled as rewards that can only be unwrapped if a set of witness objects are passed as arguments to the complete function. A witness is a struct with the drop key. The idea is to have a user complete a set of tasks for a reward in different protocols . The protocols certify that the user completed the task via their Witnesses.

Structs

Quest

struct Quest<Reward: store> has key, store {
    id: UID,
    required_tasks: VecSet<TypeName>,
    completed_tasks: VecSet<TypeName>,
    reward: Reward,
 }
  • required_tasks - Stores the Witnesses of all required tasks.

  • completed_tasks - Contains all the Witnesses the user must complete to unwrap the {Reward}.

  • reward - An object that will be returned once the Quest has been completed.

Interface

new

Creates a {Quest} .

public fun new<Reward: store>(
  required_tasks: VecSet<TypeName>, 
  reward: Reward, 
  ctx: &mut TxContext
): Quest<Reward>
  • @param required_tasks: A vector set of the required tasks to unlock the reward.

  • @param reward: An object with the store ability that can be redeemed once all tasks are completed.

  • @return Quest<Reward>.

required_tasks

Returns the required tasks of the self.

public fun required_tasks<Reward: store>(self: &Quest<Reward>): vector<TypeName>
  • @param self: A {Quest}.

  • @return vector<TypeName>. A vector of the required Witness names to complete the quest.

completed_tasks

Returns the completed tasks of the self.

public fun required_tasks<Reward: store>(self: &Quest<Reward>): vector<TypeName>
  • @param self: A {Quest}.

  • @return vector<TypeName>. A vector of the completed Witness names to complete the quest.

complete

Completes a quest by adding the witness Task name to the self.completed_tasks vector.

public fun complete<Reward: store, Task: drop>(self: &mut Quest<Reward>, _: Task)
  • @param self: A {Quest}.

  • @param: _ A witness Task.

finish

Finishes a quest and returns the Reward to the caller.

public fun complete<Reward: store, Task: drop>(self: &mut Quest<Reward>, _: Task)
  • @param self: A {Quest}.

  • @return: Reward.

Aborts

  • If the required_tasks do not match the completed_tasks

Owner

It provides an Owner capability that stores the IDs of other objects, Modules can assert or check if a certain ID is stored in the Owner to prove its ownership. It is used to provide access control.

Structs

OwnerCap

struct OwnerCap<phantom T> has key, store {
    id: UID,
    of: VecSet<ID>
 }
  • of - A set of IDs to prove that the Owner Capability has privileged access to it.

Interface

new

It creates an OwnerCap capability.

public fun new<T: drop>(_: T, of: vector<ID>, ctx: &mut TxContext): OwnerCap<T>
  • @param _: A witness to link an OwnerCap with the module that owns the witness.

  • @param of: Vector of sui::object::ID that this capability owns.

  • @return OwnerCap.

contains

It checks if an ID is stored in the Owner Capability.

public fun contains<T: drop>(self: &OwnerCap<T>, x: ID): bool 
  • @param self: An OwnerCap object.

  • @param x: The sui::object::ID of an object.

  • @return bool. True if the self owns x.

of

Returns the vector of sui::object::ID that the self owns.

public fun of<T: drop>(self: &OwnerCap<T>): vector<ID>
  • @param self: A {OwnerCap} object.

  • @return vector. The vector of sui::object::ID.

add

Assigns the self OwnerCap as the owner of x.

public fun add<T: drop>(self: &mut OwnerCap<T>, _: T, x: ID)
  • @param self: An OwnerCap object.

  • @param _: A witness to make sure only the allowed module can add sui::object::ID to the self.

  • @param x: The sui::object::ID of the object, which the self will have ownership rights to.

remove

Removes the self OwnerCap as the owner of x.

public fun remove<T: drop>(self: &mut OwnerCap<T>, _: T, x: ID)
  • @param self: An OwnerCap object.

  • @param _: A witness to make sure only the right module can add the sui::object::ID to the self.

  • @param x: The sui::object::ID of the object, which the self will lose its ownership rights to.

destroy

Destroys an OwnerCap. It does not require the of vector to be empty.

public fun destroy<T: drop>(self: OwnerCap<T>)
  • @param self: An OwnerCap object.

destroy_empty

Destroys an OwnerCap. It requires the of vector to be empty.

public fun destroy<T: drop>(self: OwnerCap<T>)
  • @param self: A OwnerCap object.

Aborts

  • If of vector is not empty.

assert_ownership

Asserts that the self owns x.

public fun destroy<T: drop>(self: OwnerCap<T>)
  • @param self: An OwnerCap object.

  • @param x: The sui::object::ID of the object, which must belong to the capability.

Aborts

  • If the ID is not owned by the capability.

Timelock

It locks any object with the store ability for a specific amount of time. We do not provide a function to read the data inside the {Timelock} to prevent capabilities from being used.

Structs

Timelock

  • unlock_time - The unlock time in milliseconds.

  • data - Any object with the store ability.

Interface

unlock_time

Returns the unlock time in milliseconds.

  • @param self: A {Timelock}

  • @return u64. The self.unlock_time.

lock

Locks the data for unlock_time milliseconds.

  • @param data: An object with the store ability.

  • @param c: The shared sui::clock::Clock object.

  • @param unlock_time: The lock period in milliseconds.

  • @return {Timelock}.

Aborts

  • unlock_time is in the past.

unlock

Unlocks a {Timelock} and returns the locked resource T.

  • @param self: A {Timelock}

  • @param c: The shared sui::clock::Clock object.

  • @return T. An object with the store ability.

Aborts

  • unlock_time has not passed.

  struct Timelock<T: store> has key, store {
    id: UID,
    unlock_time: u64,
    data: T,
  }
public fun unlock_time<T: store>(self: &Timelock<T>): u64
public fun lock<T: store>(
    data: T, 
    c: &Clock,
    unlock_time: u64,
    ctx: &mut TxContext
): Timelock<T>
public fun unlock<T: store>(self: Timelock<T>, c:&Clock): T

Collections

Bitmap

BitMaps pack 256 booleans across each bit of a single 256-bit slot of uint256 type. Hence booleans corresponding to 256 sequential indices would only consume a single slot, unlike the regular bool which would consume an entire slot for a single value.

Structs

Bitmap

struct Bitmap has key, store {
    id: UID
}

The module adds dynamic fields to the Bitmap.

Interface

new

Creates a Bitmap.

public fun new(ctx: &mut TxContext): Bitmap
  • @return AcCollection. Bitmap.

get

Checks if an indexis set to true or false in the map.

public fun get(self: &Bitmap, index: u256): bool
  • @param self: A reference to the Bitmap.

  • @param index: The slot to check if it is flagged.

  • @return bool. If the index is true or false.

set

Sets the slot index to true in self.

public fun set(self: &mut Bitmap, index: u256)
  • @param self: A reference to the Bitmap.

  • @param index: The slot we will set to true.

unset

Sets the slot index to false in self.

public fun set(self: &mut Bitmap, index: u256)
  • @param self: A reference to the Bitmap.

  • @param index: The slot we will set to false.

destroy

Destroys the self.

public fun destroy(self: Bitmap)
  • @param self: self A bitmap to destroy.

Coin Decimals

It stores information about Coins' decimals to allow protocols to fetch them. The idea is to pass a single argument CoinDecimals to functions that require several sui::coin::CoinMetadata objects.

Structs

Decimals

struct Decimals has store {
    decimals: u8, 
    scalar: u64
}
  • decimals - decimals of a sui::coin

  • scalar - The scalar of a sui::coin's decimals. It is calculated by 10^decimals. E.g. sui::sui has a scalar of 1_000_000_000 or 1e9.

CoinDecimals

struct CoinDecimals has key, store {
    id: UID
}

The Decimals struct is saved in CoinDecimals using dynamic fields.

Interface

new

It creates a new CoinDecimals.

public fun new(ctx: &mut TxContext): CoinDecimals
  • @return CoinDecimals.

contains

Checks if a coin with type CoinType has been added to self.

public fun contains<CoinType>(self: &CoinDecimals): bool
  • @param self A {CoinDecimals} object.

  • @return bool. True if the coin's decimals and scalar are in the self.

decimals

Returns the decimals of a coin with the type CoinType.

public fun decimals<CoinType>(self: &CoinDecimals): u8
  • @param self A CoinDecimals object.

  • @return u8. The decimals of the coin.

Aborts

  • CoinType has not been added to the self.

scalar

Returns the decimals scalar of a coin with type CoinType.

 public fun scalar<CoinType>(self: &CoinDecimals): u64
  • @param self A {CoinDecimals} object.

  • @return u64. The decimal's scalar. It is calculated by 10^decimals.

Aborts

  • CoinType has not been added to the self.

add

Adds the decimals and decimal scalar of a coin with type CoinType to self.

public fun add<CoinType>(self: &mut CoinDecimals, coin_metadata: &CoinMetadata<CoinType>)
  • @param self A CoinDecimals object.

  • @return coin_metadata The sui::coin::CoinMetadata of a coin with type CoinType.

Linear Vesting Wallet

Creates a Wallet that allows the holder to claim coins linearly.

Structs

Wallet

  struct Wallet<phantom T> has key, store {
    id: UID,
    balance: Balance<T>,
    start: u64,
    released: u64,
    duration: u64
  }
  • balance - Amount of tokens to give to the holder of the wallet.

  • start - The holder can start claiming tokens after this date.

  • released - Total amount of `Coin<T>` released so far.

  • duration - The duration of the vesting.

Interface

new

It creates a new Wallet.

public fun new<T>(token: Coin<T>, c: &Clock, start: u64, duration: u64, ctx: &mut TxContext): Wallet<T>
  • @param token: A sui::coin::Coin<T>.

  • @param c: The shared object sui::clock::Clock

  • @param start: Dictate when the vesting schedule starts.

  • @param duration: Dictate when the vesting schedule starts.

  • @return Wallet.

Aborts

  • start is in the past.

balance

Returns the current amount of tokens in the self.

public fun balance<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

start

Returns the vesting schedule start time.

public fun start<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

released

Returns the current amount of total released tokens from the self.

public fun released<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

duration

Returns the duration of the vesting schedule.

public fun duration<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

vesting_status

Returns the current amount of coins available to the caller based on the linear schedule.

public fun vesting_status<T>(self: &Wallet<T>, c: &Clock): u64
  • @param self: A Wallet.

  • @param c: The sui::clock::Clock shared object.

  • @return u64. A portion of the amount that can be claimed by the user.

claim

Releases the current amount of coins available to the caller based on the linear schedule.

public fun claim<T>(self: &mut Wallet<T>, c: &Clock, ctx: &mut TxContext): Coin<T>
  • @param self: A Wallet.

  • @param c: The sui::clock::Clock shared object.

  • @return Coin.

destroy_zero

Destroys a Wallet with no balance.

public fun destroy_zero<T>(self: Wallet<T>)
  • @param self: A Wallet.

Oracle

An Oracle contract that collects price reports from several feeds and ensures they are within a price range and time limit.

Structs

Oracle

  • feeds - Set of module Witnesses that are allowed to report prices.

  • time_limit - Reported prices must have a timestamp earlier than `current_timestamp - time_limit`. It is in milliseconds.

  • deviation - Reported prices must be within the following range: `leader_price + deviation % >= reported_price >= leader_price - deviation %`.

Report

  • price - Price has 18 decimals.

  • timestamp - Timestamp in milliseconds.

Price

  • oracle - the `sui::object::ID` of the Oracle this request was sent from.

  • price - The first reported price after all checks.

  • decimals - It is always 18.

  • timestamp - The time at which this price was reported.

Interface

new

Creates an Oracle with a set of feeds.

  • @param cap: An owner cap from suitears::owner. This OwnerCap will be the owner of the new Oracle.

  • @param wit: A Witness from the module that will manage this Oracle.

  • @param feeds: Feed Witnesses. Only modules in the Oracle.feeds can report a price in the Request hot potato.

  • @param time_limit: A time in milliseconds that determines how old a price timestamp can be.

  • @param deviation: A percentage that determines an acceptable price range for all reported prices.

  • @return Oracle<Witness>.

Aborts

  • feeds vector has repeated values.

  • time_limit must be higher than 0 milliseconds.

  • deviation must be higher than 0.

share

Shares the Oracle object.

  • @param self: The Oracle.

request

Creates a Request hot potato.

  • @param self: The Request will require all feeds from Oracle to be reported.

  • @return Request.

Aborts

  • self.feed is empty.

report

Adds a price Report to the Request.

  • @param request: Request hot potato.

  • @param _ : A Witness to verify the reporters.

  • @param timestamp: The timestamp of the price feed.

  • @param price: The price

  • @param decimals: The decimal houses of the price value.

  • @return Request.

Aborts

  • a feed reports more than once.

destroy_request

Destroy the Request potato and verify the price values and timestamps.

  • @param self: The Oracle that the Request was sent from.

  • @param request: The Request.

  • @param c: The shared sui::clock::Clock object.

  • @return Price.

Aborts

  • TheRequest.oracle does not match the self.id.

  • The number of reports does not match the number of feeds in the Oracle.feeds.

  • The report witnesses do not match the required feed witnesses.

  • The reported price is outside the time_limit.

  • The price falls outside the outside deviation range.

destroy_price

Destroys an Oracle object.

  • @param self: The Oracle that the Request was sent from.

  • @param cap: The suitears::owner::OwnerCap that owns the self.

Aborts

  • the cap is not the owner of self.

feeds

Returns a vector of the Oracle.feeds.

  • @param self: An Oracle object.

  • @return vector

feeds

Returns a vector of the Oracle.feeds.

  • @param self: An Oracle object.

  • @return vector

time_limit

Returns a time limit set in the Oracle.

  • @param self: An Oracle object.

  • @return vector

deviation

Returns the price deviation set in the Oracle.

  • @param self: An Oracle object.

  • @return u256

uid

Allows extensions to read dynamic fields.

  • @param self: An Oracle object.

  • @return sui::object::UID

oracle

Returns the sui::object::ID of a Price's oracle.

  • @param price: A Price potato.

  • @return sui::object::ID

price

Returns the price value of a Price hot potato.

  • @param price: A Price potato.

  • @return u256

decimals

Returns the decimal houses of the price value.

  • @param price: A Price potato.

  • @return u8

timestamp

Returns the timestamp of the a Price.

  • @param price: A Price potato.

  • @return u64

uid_mut

Allows extensions to add/remove dynamic fields.

  • @param self: An Oracle object.

  • @param cap: The suitears::owner::OwnerCap that owns the self.

  • @return sui::object::UID

Aborts

  • The cap is not the owner of self.

add

Adds a feed Witness to an Oracle.

  • @param self: An Oracle object.

  • @param cap: The suitears::owner::OwnerCap that owns the self.

  • @param feed: A Witness feed.

Aborts

  • The cap is not the owner of self.

  • A duplicated feed is added.

remove

Removes a feed Witness to an Oracle.

  • @param self: An Oracle object.

  • @param cap: The suitears::owner::OwnerCap that owns the self.

  • @param feed: A Witness feed.

Aborts

  • The cap is not the owner of self.

  • The Oracle has 1 feed left.

update_time_limit

Updates the time_limit of an Oracle.

  • @param self: An Oracle object.

  • @param cap: The suitears::owner::OwnerCap that owns the self.

  • @param time_limit: The new time_limit.

Aborts

  • The cap is not the owner of self.

  • The time_limit cannot be zero.

update_deviation

Updates the deviation of an Oracle.

  • @param self: An Oracle object.

  • @param cap: The suitears::owner::OwnerCap that owns the self.

  • @param deviation: The new deviation.

Aborts

  • The cap is not the owner of self.

  • The time_limit cannot be zero.

new_price_for_testing

Creates a Price for testing purposes only. Only available in tests.

  • @param oracle: sui::object::ID of theOracle this request was sent from.

  • @param price: The reported price.

  • @param decimals: The decimals precision of price.

  • @param timestamp: The timestamp in milliseconds in which the price was recorded.

 struct Oracle<phantom Witness: drop> has key, store {
    id: UID,
    // Set of module Witnesses that are allowed to report prices.
    feeds: VecSet<TypeName>,
    // Reported prices must have a timestamp earlier than `current_timestamp - time_limit`. 
    // It is in milliseconds. 
    time_limit: u64,
    // Reported prices must be within the following range: `leader_price + deviation % >= reported_price >= leader_price - deviation %`.
    deviation: u256
  }  
struct Report has store, copy, drop {
    price: u256,
    timestamp: u64
 }
struct Price {
    // `sui::object::ID` of the`Oracle` this request was sent from.
    oracle: ID,
    // The first reported price. 
    // Price has 18 decimals.  
    price: u256,
    // It is always 18.  
    decimals: u8, 
    // The price was reported at this time.  
    timestamp: u64    
 }
public fun new<Witness: drop>(
  cap: &mut OwnerCap<Witness>,
  wit: Witness, 
  feeds: vector<TypeName>, 
  time_limit: u64, 
  deviation: u256, 
  ctx: &mut TxContext
): Oracle<Witness>
public fun share<Witness: drop>(self: Oracle<Witness>)
public fun request<Witness: drop>(self: &Oracle<Witness>): Request
public fun report<Witness: drop>(request: &mut Request, _: Witness, timestamp: u64, price: u128, decimals: u8)
public fun destroy_request<Witness: drop>(self: &Oracle<Witness>, request: Request, c: &Clock): Price
public fun destroy_oracle<Witness: drop>(self: Oracle<Witness>)
public fun feeds<Witness: drop>(self: &Oracle<Witness>): vector<TypeName>
public fun feeds<Witness: drop>(self: &Oracle<Witness>): vector<TypeName>
public fun feeds<Witness: drop>(self: &Oracle<Witness>): vector<TypeName>
public fun deviation<Witness: drop>(self: &Oracle<Witness>): u256
public fun uid<Witness: drop>(self: &Oracle<Witness>): &UID
public fun oracle(price: &Price): ID
public fun price(price: &Price): u256
public fun decimals(price: &Price): u8
public fun timestamp(price: &Price): u64
public fun uid_mut<Witness: drop>(self: &mut Oracle<Witness>, cap: &OwnerCap<Witness>): &mut UID
public fun add<Witness: drop>(self: &mut Oracle<Witness>, cap: &OwnerCap<Witness>, feed: TypeName)
public fun remove<Witness: drop>(self: &mut Oracle<Witness>, cap: &OwnerCap<Witness>, feed: TypeName)
public fun update_time_limit<Witness: drop>(self: &mut Oracle<Witness>, cap: &OwnerCap<Witness>, time_limit: u64)
public fun update_deviation<Witness: drop>(self: &mut Oracle<Witness>, cap: &OwnerCap<Witness>, deviation: u256)
#[test_only]
public fun new_price_for_testing(
 oracle: ID,
 price: u256,
 decimals: u8,
 timestamp: u64
): Price

Fund

It is a utility struct to easily know how many shares to issue/burn based on an underlying amount.

Structs

Account

struct Fund has store, copy, drop {
    shares: u128,
    underlying: u128
 }
  • shares - The amount of shares issued based on the underlying amount.

  • underlying - The amount of assets in the fund.

Interface

empty

Creates an empty Fund.

public fun empty(): Fund
  • @return Fund.

underlying

Returns the amount of underlying in the self.

public fun underlying(self: &Fund): u64
  • @param self: A Fund.

  • @return u64. The amount of underlying.

shares

Returns the amount of shares in the self.

public fun shares(self: &Fund): u64
  • @param self: A Fund.

  • @return u64. The amount of shares.

to_shares

Returns the number of shares the self would issue if more underlying was deposited in it.

public fun to_shares(self: &Fund, underlying: u64, round_up: bool): u64
  • @param self: A Fund.

  • @param underlying: The amount of underlying that the caller intends to add to the self.

  • @param round_up: If true we would round up the returned value.

  • @return u64. The amount of shares the fund would issue.

to_underlying

Returns the number of shares the self would issue if more underlying was deposited in it.

public fun to_underlying(rebase: &Fund, shares: u64, round_up: bool): u64
  • @param self: A Fund.

  • @param shares: The amount of shares that the caller intends to burn.

  • @param round_up: If true we would round up the returned value.

  • @return u64. The amount underlying the fund would release.

sub_shares

This function reduces the amount of underlying and shares in the fund.

public fun sub_shares(self: &mut Fund, shares: u64, round_up: bool): u64
  • @param self: A Fund.

  • @param shares: The amount of shares that the caller intends to burn.

  • @param round_up: If true we would round up the returned value.

  • @return u64. The amount underlying the shares were worth.

add_underlying

Adds underlying to the self and returns the additional shares issued. This function increases the amount of underlying and shares in the fund.

public fun add_underlying(rebase: &mut Fund, underlying: u64, round_up: bool): u64
  • @param self: A Fund.

  • @param underlying: The amount of underlying to deposit in the self.

  • @param round_up: If true we would round up the returned value.

  • @return u64. The amount of shares the fund issued.

sub_underlying

Removes underlying from the self and returns the burned shares. This function reduces the amount of underlying and shares in the fund.

public fun sub_underlying(rebase: &mut Fund, underlying: u64, round_up: bool): u64
  • @param self: A Fund.

  • @param underlying: The amount of underlying to remove from the self.

  • @param round_up: If true we would round up the returned value.

  • @return u64. The amount of shares the fund burned.

add_profit

Adds profits to the underlying. This is to add profits to the fund.

public fun add_profit(rebase: &mut Fund, profit: u64)
  • @param self: A Fund.

  • @param profit: The amount of underlying to add as profit to self.underlying.

Linear Clawback Vesting Wallet

Creates a Wallet that allows the holder to claim coins linearly. The holder of the OwnerCap can reclaim any locked coins back.

Structs

Wallet

  struct Wallet<phantom T> has key, store {
    id: UID,
    balance: Balance<T>,
    start: u64,
    released: u64,
    duration: u64,
    clawbacked: u64
  }
  • balance - Amount of tokens to give to the holder of the wallet.

  • start - The holder can start claiming tokens after this date.

  • released - Total amount of `Coin<T>` released so far.

  • duration - The duration of the vesting.

  • clawbacked - The amount of tokens recalled.

Interface

new

It creates a new Wallet and two capabilities for the recipient and the clawback owner.

  public fun new<T>(
    token: Coin<T>, 
    c: &Clock, 
    start: u64, 
    duration: u64, 
    ctx: &mut TxContext
  ): (OwnerCap<ClawBackWitness>, OwnerCap<RecipientWitness>, Wallet<T>)
  • @param token: A sui::coin::Coin<T>.

  • @param c: The shared object sui::clock::Clock

  • @param start: Dictate when the vesting schedule starts.

  • @param duration: Dictate when the vesting schedule starts.

  • @return OwnerCap<ClawBackWitness>: The holder of this capability can claw back the coins.

  • @return OwnerCap<RecipientWitness>: The holder of this capability can claim tokens according to the linear schedule.

  • @return Wallet.

Aborts

  • start is in the past.

share

It shares the Wallet with the network.

public fun share<T>(self: Wallet<T>)
  • @param self: A Wallet.

balance

Returns the current amount of tokens in the self.

public fun balance<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

start

Returns the vesting schedule start time.

public fun start<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

released

Returns the current amount of total released tokens from the self.

public fun released<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

duration

Returns the duration of the vesting schedule.

public fun duration<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

clawbacked

Returns the number of tokens that were claw-backed by the holder of OwnerCap from the self.

public fun clawbacked<T>(self: &Wallet<T>): u64
  • @param self: A Wallet.

  • @return u64.

vesting_status

Returns the current amount of coins available to the caller based on the linear schedule.

public fun vesting_status<T>(self: &Wallet<T>, c: &Clock): u64
  • @param self: A Wallet.

  • @param c: The sui::clock::Clock shared object.

  • @return u64. A portion of the amount that can be claimed by the user.

claim

Releases the current amount of coins available to the caller based on the linear schedule.

public fun claim<T>(self: &mut Wallet<T>, cap: &OwnerCap<RecipientWitness>, c: &Clock, ctx: &mut TxContext): Coin<T>
  • @param self: A Wallet.

  • @param cap: The recipient capability that owns the self.

  • @param c: The sui::clock::Clock shared object.

  • @return Coin.

Aborts

  • cap does not own the self.

clawback

Returns all unreleased coins to the cap holder.

public fun clawback<T>(self: &mut Wallet<T>, cap: OwnerCap<ClawBackWitness>, c: &Clock, ctx: &mut TxContext): Coin<T>
  • @param self: A Wallet.

  • @param cap: The clawback capability that owns the self.

  • @param c: The sui::clock::Clock shared object.

  • @return Coin.

Aborts

  • cap does not own the self.

destroy_zero

Destroys a Wallet with no balance.

public fun destroy_zero<T>(self: Wallet<T>)
  • @param self: A Wallet.

Farm

A contract to distribute reward tokens to stakers.

All times are in seconds.

Structs

Account

  struct Account<phantom StakeCoin, phantom RewardCoin> has key, store {
    id: UID,
    farm_id: ID, 
    amount: u64,
    reward_debt: u256
  }
  • farm_id - The `sui::object::ID` of the farm to which this account belongs to.

  • amount - The amount of StakeCoin the user has in the Farm.

  • reward_debt - Amount of rewards the Farm has already paid the user.

Farm

struct Farm<phantom StakeCoin, phantom RewardCoin> has key, store {
    id: UID,  
    rewards_per_second: u64,
    start_timestamp: u64,
    last_reward_timestamp: u64, 
    accrued_rewards_per_share: u256,
    balance_stake_coin: Balance<StakeCoin>,
    balance_reward_coin: Balance<RewardCoin>,
    stake_coin_decimal_factor: u64,
    owned_by: ID
 }
  • rewards_per_second - Amount of RewardCoin to give to stakers per second.

  • start_timestamp - The timestamp in seconds that this farm will start distributing rewards.

  • last_reward_timestamp - Last timestamp that the farm was updated.

  • accrued_rewards_per_share - Total amount of rewards per share distributed by this farm.

  • balance_stake_coin - StakeCoin deposited in this farm.

  • balance_reward_coin - RewardCoin deposited in this farm.

  • stake_coin_decimal_factor - The decimal scalar of the StakeCoin.

  • owned_by - The `sui::object::ID` of the OwnerCap that "owns" this farm.

Interface

new_cap

It creates an OwnerCap. It is used to provide admin capabilities to the holder.

public fun new_cap(ctx: &mut TxContext): OwnerCap<FarmWitness>
  • @return OwnerCap.

new_farm

It creates an Farm<StakeCoin, RewardCoin>. The start_timestamp is in seconds.

public fun new_farm<StakeCoin, RewardCoin>(
    cap: &mut OwnerCap<FarmWitness>,
    stake_coin_metadata: &CoinMetadata<StakeCoin>,
    c: &Clock,
    rewards_per_second: u64,
    start_timestamp: u64,
    ctx: &mut TxContext
 ): Farm<StakeCoin, RewardCoin>
  • @param cap: An OwnerCap that will be assigned the admin rights of the newly created Farm.

  • @param stake_coin_metadata: The sui::coin::CoinMetadata of the StakeCoin.

  • @param c: The sui::clock::Clock shared object.

  • @param rewards_per_second: The amount of RewardCoin the farm can distribute to stakers.

  • @param start_timestamp: The timestamp in seconds that the farm is allowed to start distributing rewards.

  • @return Farm<StakeCoin, RewardCoin>.

new_account

It creates an Account<StakeCoin, RewardCoin>. It is used to keep track of the holder's deposit and rewards.

public fun new_account<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>, ctx: &mut TxContext): Account<StakeCoin, RewardCoin>
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return Account<StakeCoin, RewardCoin>.

rewards_per_second

Returns the self rewards per second.

public fun rewards_per_second<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>): u64
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u64.

start_timestamp

Returns the self start timestamp.

public fun start_timestamp<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>): u64
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u64.

last_reward_timestamp

Returns the self last reward timestamp.

public fun last_reward_timestamp<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>): u64
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u64.

accrued_rewards_per_share

Returns the self accrued rewards per share.

public fun accrued_rewards_per_share<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>): u256
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u256.

balance_stake_coin

Returns the self stake coin balance.

public fun balance_stake_coin<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>): u64
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u64.

balance_reward_coin

Returns the self reward coin balance.

public fun balance_reward_coin<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>): u64
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u64.

stake_coin_decimal_factor

Returns the self reward coin decimal scalar.

public fun stake_coin_decimal_factor<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>): u64
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u64.

owned_by

Returns the self reward coin decimal scalar.

public fun owned_by<StakeCoin, RewardCoin>(self: &Farm<StakeCoin, RewardCoin>): ID
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return ID.

amount

Returns the account staked amount.

public fun amount<StakeCoin, RewardCoin>(account: &Account<StakeCoin, RewardCoin>): u64
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u64.

reward_debt

Returns the account reward debt.

public fun reward_debt<StakeCoin, RewardCoin>(account: &Account<StakeCoin, RewardCoin>): u256
  • @param cap: self The Farm<StakeCoin, RewardCoin>.

  • @return u256.

pending_rewards

Returns the account's pending rewards. It does not update the state.

public fun pending_rewards<StakeCoin, RewardCoin>(
    farm: &Farm<StakeCoin, RewardCoin>, 
    account: &Account<StakeCoin, RewardCoin>,
    c: &Clock, 
 ): u64
  • @param farm: The Farm<StakeCoin, RewardCoin>.

  • @param account: The Account associated with the farm.

  • @param c: The sui::clock::Clock shared object.

  • @return u64.

add_rewards

It allows anyone to add rewards to the farm.

public fun add_rewards<StakeCoin, RewardCoin>(self: &mut Farm<StakeCoin, RewardCoin>, c: &Clock, reward: Coin<RewardCoin>)
  • @param self: The Farm<StakeCoin, RewardCoin>.

  • @param c: The sui::clock::Clock shared object.

  • @param reward: The RewardCoin to be added to the self.

stake

Allows a user to stake stake_coin in the farm. On the first deposits the returned Coin will have a value of zero. So make sure to destroy it.

public fun stake<StakeCoin, RewardCoin>(
    farm: &mut Farm<StakeCoin, RewardCoin>, 
    account: &mut Account<StakeCoin, RewardCoin>,
    stake_coin: Coin<StakeCoin>, 
    c: &Clock,
    ctx: &mut TxContext
): Coin<RewardCoin>
  • @param farm: The Farm<StakeCoin, RewardCoin>.

  • @param account: The Account associated with the farm.

  • @param stake_coin: The StakeCoin to stake in the farm.

  • @param c: The sui::clock::Clock shared object.

  • @return Coin. It gives any pending rewards to the user.

Aborts

  • If the account does not belong to the farm.

unstake

Allows a user to unstake his stake_coin in the farm.

public fun unstake<StakeCoin, RewardCoin>(
    farm: &mut Farm<StakeCoin, RewardCoin>, 
    account: &mut Account<StakeCoin, RewardCoin>,
    amount: u64,
    c: &Clock,
    ctx: &mut TxContext
 ): (Coin<StakeCoin>, Coin<RewardCoin>)
  • @param farm: The Farm<StakeCoin, RewardCoin>.

  • @param account: The Account associated with the farm.

  • @param amount: The amount of StakeCoin to remove from the farm.

  • @param c: The sui::clock::Clock shared object.

  • @return Coin. The staked Coin.

  • @return Coin. It gives any pending rewards to the user.

Aborts

  • amount is larger than the account.amount. If the user tries to unstake more than he has staked.

destroy_zero_account

Destroys the account.

public fun destroy_zero_account<StakeCoin, RewardCoin>(account: Account<StakeCoin, RewardCoin>)
  • @param account: The Account associated with the farm.

Aborts

  • account has an amount greater than zero.

update_rewards_per_second

Updates the rewards per second of the farm.

public fun update_rewards_per_second<StakeCoin, RewardCoin>(
    farm: &mut Farm<StakeCoin, RewardCoin>,     
    cap: &OwnerCap<FarmWitness>, 
    new_rewards_per_second: u64,
    c: &Clock
)
  • @param farm: The Farm<StakeCoin, RewardCoin>.

  • @param cap: The OwnerCap that "owns" the farm.

  • @param new_rewards_per_second: The new amount of RewardCoin the farm will give.

  • @param c: The sui::clock::Clock shared object.

Aborts

  • cap does not own the farm.

destroy_zero_farm

Destroys the farm.

public fun destroy_zero_farm<StakeCoin, RewardCoin>(farm: Farm<StakeCoin, RewardCoin>, cap: &OwnerCap<FarmWitness>)
  • @param farm: The Farm<StakeCoin, RewardCoin>.

  • @param cap: The OwnerCap that "owns" the farm.

Aborts

  • cap does not own the farm.

  • farm still has staked coins.

  • farm still has reward coins.

borrow_mut_uid

Returns a mutable reference of the farm's sui::object::UI to allow the cap owner to extend its functionalities.

public fun borrow_mut_uid<StakeCoin, RewardCoin>(farm: &mut Farm<StakeCoin, RewardCoin>, cap: &OwnerCap<FarmWitness>): &mut UID
  • @param farm: The Farm<StakeCoin, RewardCoin>.

  • @param cap: The OwnerCap that "owns" the farm.

  • @return &mut UID.

Aborts

  • cap does not own the farm.

DAO

It allows anyone to create a DAO, submit proposals, and execute actions on-chain.

  • Proposals are voted by depositing coins. 1 Coin is 1 Vote.

  • DAOs only supports 1 Coin type

The idea is to send capabilities to the DAO via sui::transfer::transfer.

  • Users can borrow the capabilities via successful proposals.

  • Developers must write custom modules that pass the AuthorizedWitness to borrow the capability when executing proposals.

  • DAO relies on open-source code to make sure the Modules that are executing proposals do what they agreed to do.

A Successful Proposal requires:

  • for_votes > agaisnt_votes

  • for_votes / total_votes > quorum rate

  • for_votes >= min_quorum_votes

Each Vote struct belongs to a specific Proposal via the vote.proposal_id field.

  • A voter can revoke his vote and recover his sui::coin::Coin if the Proposal is active.

  • A voter can recover his coins once the voting period ends.

  • A Vote created from ProposalA cannot be used in ProposalB.

Proposal States

Pending: Newly created proposal.

Active: Proposal is open for voting.

Defeated: The proposal did not pass.

Agree: The proposal passed.

Queued: The proposal was successful and now it is in a queue to be executed if it is executable. This gives time for people to adjust to the upcoming change.

Executable: It can be executed.

Finished: The proposal has been executed.

Structs

DAO

  • voting_delay - Voters must wait `voting_delay` in milliseconds to start voting on new proposals.

  • voting_period- The voting duration of a proposal.

  • voting_quorum_rate

    • The minimum quorum rate to pass a proposal.

    • If 50% votes are needed, then the voting_quorum_rate should be 5_00_000_000.

    • It should be between (0, 1e9].

  • min_action_delay - How long the proposal should wait before it can be executed (in milliseconds).

  • min_quorum_votes - Minimum amount of votes for a Proposal to be successful even if it is higher than the against votes and the quorum rate.

  • treasury - The `sui::object::ID` of the Treasury.

  • coin_type - The CoinType that can vote on this DAO's proposal.

  • admin_id - The DaoAdmin.

Proposal

  • proposer - The user who created the proposal.

  • start_time - When the users can start voting.

  • end_time - Users can no longer vote after the end_time.

  • for_votes- How many votes support the Proposal.

  • agaisnt_votes- How many votes disagree with the Proposal.

  • eta

    • It is calculated by adding end_time and action_delay. It assumes the Proposal will be executed as soon as possible.

    • Estimated Time of Arrival.

  • action_delay

    • Time Delay between a successful Proposal end_time and when it is allowed to be executed.

    • It allows users who disagree with the proposal to make changes.

  • quorum_votes - The minimum amount of for_votes for a Proposal to pass.

  • voting_quorum_rate - The minimum support rate for a Proposal to pass.

  • hash - The hash of the description of this proposal.

  • authorized_witness

    • The Witness that is allowed to call execute.

    • Not executable proposals do not have an authorized_witness.

  • capability_id

    • The sui::object::ID that this proposal needs to execute.

    • Not all proposals are executable.

  • coin_type - The CoinType of the DAO

Capability Request - Hot Potato

  • capability_id - The sui::object::ID of the borrowed Capability.

  • dao_id: The DAO that owns said Capability.

Vote

  • balance - The amount of Coin the user has used to vote for the Proposal.

  • proposal_id: The sui::object::ID of the Proposal.

  • end_time:

    • The end_time of the Proposal.

    • User can redeem back his balance after this timestamp.

  • agree - If it is a for or against vote.

Interface

new

It creates a DAO with Treasury.

  • @param otw: A One Time Witness to ensure that the Dao is unique.

  • @param voting_delay: The minimum waiting period between the creation of a proposal and the voting period.

  • @param voting_period: The duration of the voting period.

  • @param voting_quorum_rate: The minimum percentage of votes to pass a proposal. E.g. for_votes / total_votes. keep in mind (0, 1_000_000_000]

  • @param min_action_delay: The minimum delay required to execute a proposal after it passes.

  • @param min_quorum_votes: The minimum votes required for a Proposal to be successful.

  • @return Dao<OTW>

  • @return Treasury<OTW>

Aborts

  • otw is not a One Time Witness.

  • voting_quorum_rate is larger than 1_000_000_000

  • voting_quorum_rate is zero.

voting_delay

Returns the minimum voting delay of the Dao.

  • @param self: a Dao

  • @return u64

voting_period

Returns the minimum voting period of the Dao.

  • @param self: a Dao

  • @return u64

dao_voting_quorum_rate

Returns the minimum voting quorum rate of the Dao.

  • @param self: a Dao

  • @return u64

min_action_delay

Returns the minimum action delay of the Dao.

  • @param self: a Dao

  • @return u64

min_quorum_votes

Returns the minimum votes required to pass a proposal.

  • @param self: a Dao

  • @return u64

treasury

Returns the sui::object::id of the Dao wrapped in an std::option.

  • @param self: a Dao

  • @return ID

dao_coin_type

Returns the std::type_name of the Dao's coin type. This is the Coin that can be used to vote on proposals.

  • @param self: a Dao

  • @return TypeName

admin

Returns the sui::object::ID of Dao's admin capability. It is used to update the Dao's settings and transfer coins from the treasury.

  • @param self: a Dao

  • @return ID

proposer

Returns the address of the user who created the proposal.

  • @param proposal: The Proposal

  • @return address

start_time

Returns start timestamp of the proposal.

  • @param proposal: The Proposal.

  • @return u64

end_time

Returns end timestamp of the proposal.

  • @param proposal: The Proposal.

  • @return u64

for_votes

Returns the number of votes that support this proposal.

  • @param proposal: The Proposal.

  • @return u64

agaisnt_votes

Returns the number of votes against this proposal.

  • @param proposal: The {Proposal}.

  • @return u64

eta

Returns an estimation of when a successful proposal will be executed.

  • @param proposal: The Proposal.

  • @return u64

action_delay

Returns the minimum time a successful proposal has to wait before it can be executed.

  • @param proposal: The Proposal.

  • @return u64

quorum_votes

Returns the minimum number of votes required for a successful proposal.

  • @param proposal: The Proposal.

  • @return u64

voting_quorum_rate

Returns the minimum rate for a proposal to pass. Formula: for_votes / total_votes. 100% is represented by 1_000_000_000.

  • @param proposal: The Proposal.

  • @return u64

hash

Returns the hash of the description of the proposal.

  • @param proposal: The Proposal.

  • @return vector<u8>

authorized_witness

Returns the std::type_name::TypeName of the Witness that can execute the proposal.

  • @param proposal: The Proposal.

  • @return TypeName

capability_id

Returns the sui::object::ID of the Capability that the proposal requires to execute.

  • @param proposal: The Proposal.

  • @return Option<ID>

coin_type

Returns the CoinType of the proposal. Votes must use this CoinType.

  • @param proposal: The Proposal.

  • @return TypeName

balance

Returns the number of votes.

  • @param vote: The Vote<DaoWitness, CoinType>.

  • @return u64

proposal_id

Returns the Proposal sui::object::ID.

  • @param vote: The Vote<DaoWitness, CoinType>.

  • @return ID

vote_end_time

Returns the ending timestamp of the proposal. Users can withdraw their deposited coins afterward.

  • @param vote: The Vote<DaoWitness, CoinType>.

  • @return u64

agree

Returns if it is a for or against vote.

  • @param vote: The Vote<DaoWitness, CoinType>.

  • @return bool

state

Returns the proposal state.

  • @param vote: The Vote<DaoWitness, CoinType>.

  • @return u8

propose

Creates a Proposal.

  • @param dao: The Dao.

  • @param c: The shared sui::clock::Clock object.

  • @param authorized_witness: The Witness required to execute this proposal.

  • @param capability_id: The sui::object::ID of the Capability that this proposal needs to be executed. If a proposal is not executable pass option::none()

  • @param action_delay: The minimum waiting period for a successful Proposal to be executed.

  • @param quorum_votes: The minimum waiting period for a successful Proposal to be executed.

  • @param hash: The hash of the proposal's description.

  • @return Proposal<DaoWitness>

Abort

  • action_delay < dao.min_action_delay.

  • quorum_votes < dao.min_quorum_votes.

  • hash is empty.

cast_vote

Allows a user to use coins to vote for a proposal, either against or for depending on agree.

  • @param proposal: The proposal the user is voting for.

  • @param c: The shared sui::clock::Clock object.

  • @param stake: The coin that the user will deposit to vote.

  • @param agree: Determines if the vote is for or against..

  • @return Vote<DaoWitness, CoinType>

Aborts

  • if the proposal is not ACTIVE

  • if the stake type does not match the proposal.coin_type

  • if a user tries to vote with a zero coin stake.

change_vote

Allows a user to change his vote for a proposal.

  • @param proposal: The proposal the user is voting for.

  • @param vote: The vote that will be changed.

  • @param c: The shared sui::clock::Clock object.

Aborts

  • if the proposal is not ACTIVE

  • if the vote does not belong to the proposal.

revoke_vote

Allows a user to revoke his vote for a proposal and get his coin back.

  • @param proposal: The proposal the user is voting for.

  • @param vote: The vote that will be destroyed.

  • @param c: The shared sui::clock::Clock object.

  • @return Coin<CoinType>

Aborts

  • if the proposal is not ACTIVE

  • if the vote does not belong to the proposal.

unstake_vote

Allows a user to unstake his vote to get his coins back after the proposal has ended.

  • @param proposal: The proposal the user is voting for.

  • @param vote: The vote that will be destroyed.

  • @param c: The shared sui::clock::Clock object.

  • @return Coin<CoinType>

Aborts

  • if the proposal has not ended.

  • if the vote type does not match the proposal.id

queue

Allows a successful proposal to be queued.

  • @param proposal: The proposal the user is voting for.

  • @param c: The shared sui::clock::Clock object.

Aborts

  • if the proposal state is not AGREED.

execute

Executes a proposal.

  • @param dao: The Dao.

  • @param proposal: The proposal that will be executed.

  • @param _: The witness that is authorized to borrow the Capability.

  • @param receive_ticket: A receipt struct to borrow the Capability.

  • @param c: The shared sui::clock::Clock object.

  • @return Capability required to execute the proposal.

  • @return CapabilityRequest A hot potato to ensure that the borrower returns the Capability to the dao.

Aborts

  • if the proposal state is not EXECUTABLE

  • if there has not passed enough time since the end_time

  • if the Authorized Witness does not match the proposal.authorized_witness.

  • if the borrowed capability does not match the proposal.capability_id.

return_capability

Returns the borrowed cap to the dao.

  • @param dao: The Dao.

  • @param cap: The capability that will be returned to the dao.

  • @param receipt: The request hot potato.

Aborts

  • if the user tries to return the cap to the wrong dao

  • if there user tries to return the wrong cap

update_dao_config

Updates the configuration settings of the dao.

  • @param dao: The Dao.

  • @param _: Immutable reference to the DaoAdmin.

  • @param voting_delay: The minimum waiting period between the creation of a proposal and the voting period.

  • @param voting_period: The duration of the voting period.

  • @param voting_quorum_rate: The minimum percentage of votes. E.g. for_votes / total_votes. Range = (0, 1_000_000_000]

  • @param min_action_delay: The delay required to execute a proposal after it passes.

  • @param min_quorum_votes: The minimum votes required for a {Proposal} to be successful.

Aborts

  • if the user tries to return the cap to the wrong dao

  • if there user tries to return the wrong cap

DAO Admin

It creates a capability to enable Daos to update their settings and interact with the treasury. Only the DAO module can create the DaoAdmin capability.

Structs

DaoAdmin

Vesting

A utility module to provide virtual implementations of vesting schedules.

Interface

new

Calculates the amount that has already vested.

  • @param start: The beginning of the vesting schedule.

  • @param duration: The duration of the schedule.

  • @param balance: The current amount of tokens in the wallet.

  • @param already_released: The total amount of tokens released.

  • @param timestamp: The current time in milliseconds.

  • @return u64. The vested amount.

DAO Treasury

A Treasury for DAOs. It can receive and send sui::coin::Coin.

Structs

DaoTreasury

  • coins - Stores the treasury coins

  • dao- The sui::object::ID of the DAO.

DaoTreasury

  • amounts: The amount being borrowed

  • fee- The fee amount to be repaid.

  • type: The std::type_name::TypeName of the CoinType to repay the loan.

Interface

dao

Returns the sui::object::ID of the Dao that owns the treasury.

  • @param treasury: A DaoTreasury.

  • @return ID

balance

Returns the amount of Coin in the treasury.

  • @param treasury: A DaoTreasury.

  • @return u64

donate

Adds token to the treasury.

  • @param treasury A DaoTreasury.

  • @param token It will be donated to the treasury.

transfer

Withdraws a coin from the treasury.

  • @param treasury: A DaoTreasury.

  • @param _ : Immutable reference to the DaoAdmin.

  • @param value : The amount to withdraw.

  • @return Coin

transfer_linear_vesting_wallet

Withdraws a LinearWallet from the treasury.

  • @param treasury: A DaoTreasury.

  • @param _ : Immutable reference to the DaoAdmin.

  • @param c: The sui::clock::Clock

  • @param value : The amount to withdraw.

  • @param start : The amount to withdraw.

  • @param duration : The duration of the vesting schedule.

  • @return LinearWallet.

flash_loan

Requests a Flash Loan from the treasury.

  • @param treasury: A DaoTreasury.

  • @param value : The amount of the loan.

  • @return Coin<CoinType>. The coin that is being borrowed.

  • @return FlashLoan<DaoWitness, CoinType>. Hot potato to ensure that the coin is returned within the same transaction block.

fee

Returns the service fee amount that must be paid.

  • @param flash_loan: A FlashLoan hot potato.

  • @return u64.

amount

Returns the amount of the loan without the fees.

  • @param flash_loan: A FlashLoan hot potato.

  • @return u64.

repay_flash_loan

Repays the flash_loan to the treasury.

  • @param treasury: A DaoTreasury.

  • @param flash_loan: A FlashLoan hot potato.

  • @param token: The borrowed coin + fee.

Aborts

  • token.value is smaller than the initial loan amount + fee amount.

struct Dao<phantom OTW> has key, store {
    id: UID,
    voting_delay: u64, 
    voting_period: u64,
    voting_quorum_rate: u64,
    min_action_delay: u64, 
    min_quorum_votes: u64,
    treasury: ID,
    coin_type: TypeName,
    admin_id: ID
 }
  struct Proposal<phantom DaoWitness: drop> has key, store {
    id: UID,
    proposer: address,
    start_time: u64,
    end_time: u64,
    for_votes: u64,
    against_votes: u64,
    eta: u64,  
    action_delay: u64, 
    quorum_votes: u64, 
    voting_quorum_rate: u64, 
    hash: String,
    authorized_witness: Option<TypeName>, 
    capability_id: Option<ID>,
    coin_type: TypeName
  }
  struct CapabilityRequest {  
    capability_id: ID,
    dao_id: ID
  }
  struct Vote<phantom DaoWitness: drop, phantom CoinType> has  key, store {
    id: UID,
    balance: Balance<CoinType>,
    proposal_id: ID,
    end_time: u64,
    agree: bool
  } 
public fun new<OTW: drop, CoinType: drop>(
    otw: OTW, 
    voting_delay: u64, 
    voting_period: u64, 
    voting_quorum_rate: u64, 
    min_action_delay: u64, 
    min_quorum_votes: u64,
    ctx: &mut TxContext
): (Dao<OTW>, DaoTreasury<OTW>)
public fun voting_delay<DaoWitness>(self: &Dao<DaoWitness>): u64
public fun voting_period<DaoWitness>(self: &Dao<DaoWitness>): u64
public fun dao_voting_quorum_rate<DaoWitness>(self: &Dao<DaoWitness>): u64
public fun min_action_delay<DaoWitness>(self: &Dao<DaoWitness>): u64
public fun min_quorum_votes<DaoWitness>(self: &Dao<DaoWitness>): u64
public fun treasury<DaoWitness>(self: &Dao<DaoWitness>): ID
public fun dao_coin_type<DaoWitness>(self: &Dao<DaoWitness>): TypeName
public fun admin<DaoWitness>(self: &Dao<DaoWitness>): ID
public fun proposer<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): address
public fun start_time<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): u64
public fun end_time<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): u64
public fun for_votes<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): u64
public fun against_votes<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): u64
public fun eta<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): u64
public fun action_delay<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): u64
public fun quorum_votes<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): u64
public fun voting_quorum_rate<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): u64
public fun hash<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): String
public fun authorized_witness<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): Option<TypeName>
public fun capability_id<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): Option<ID>
public fun coin_type<DaoWitness: drop>(proposal: &Proposal<DaoWitness>): TypeName
public fun balance<DaoWitness: drop, CoinType>(vote: &Vote<DaoWitness,  CoinType>): u64
public fun proposal_id<DaoWitness: drop, CoinType>(vote: &Vote<DaoWitness,  CoinType>): ID
public fun vote_end_time<DaoWitness: drop, CoinType>(vote: &Vote<DaoWitness,  CoinType>): u64
public fun agree<DaoWitness: drop, CoinType>(vote: &Vote<DaoWitness,  CoinType>): bool
public fun agree<DaoWitness: drop, CoinType>(vote: &Vote<DaoWitness,  CoinType>): bool
public fun propose<DaoWitness: drop>(
    dao: &mut Dao<DaoWitness>,
    c: &Clock,
    authorized_witness: Option<TypeName>,
    capability_id: Option<ID>,
    action_delay: u64,
    quorum_votes: u64,
    hash: String,
    ctx: &mut TxContext    
 ): Proposal<DaoWitness>
  public fun cast_vote<DaoWitness: drop, CoinType>(
    proposal: &mut Proposal<DaoWitness>,
    c: &Clock,
    stake: Coin<CoinType>,
    agree: bool,
    ctx: &mut TxContext
  ): Vote<DaoWitness, CoinType>
public fun change_vote<DaoWitness: drop, CoinType>(
    proposal: &mut Proposal<DaoWitness>,
    vote: &mut Vote<DaoWitness,  CoinType>,
    c: &Clock,
    ctx: &mut TxContext
 )
public fun revoke_vote<DaoWitness: drop, CoinType>(
    proposal: &mut Proposal<DaoWitness>,
    vote: Vote<DaoWitness, CoinType>,
    c: &Clock,
    ctx: &mut TxContext    
 ): Coin<CoinType>
public fun unstake_vote<DaoWitness: drop, CoinType>(
    proposal: &Proposal<DaoWitness>,
    vote: Vote<DaoWitness, CoinType>,
    c: &Clock,
    ctx: &mut TxContext      
): Coin<CoinType>
public fun queue<DaoWitness: drop>(
    proposal: &mut Proposal<DaoWitness>, 
    c: &Clock
 )
public fun execute<DaoWitness: drop, AuhorizedWitness: drop, Capability: key + store>(
    dao: &mut Dao<DaoWitness>,
    proposal: &mut Proposal<DaoWitness>, 
    _: AuhorizedWitness,
    receive_ticket: Receiving<Capability>,
    c: &Clock
): (Capability, CapabilityRequest)
public fun return_capability<DaoWitness: drop, Capability: key + store>(dao: &Dao<DaoWitness>, cap: Capability, receipt: CapabilityRequest)
public fun update_dao_config<DaoWitness: drop>(
    dao: &mut Dao<DaoWitness>,
    _: &DaoAdmin<DaoWitness>,
    voting_delay: Option<u64>, 
    voting_period: Option<u64>, 
    voting_quorum_rate: Option<u64>, 
    min_action_delay: Option<u64>, 
    min_quorum_votes: Option<u64>
)
  struct DaoAdmin<phantom OTW: drop> has key, store {
    id: UID
  }
public fun linear_vested_amount(start: u64, duration: u64, balance: u64, already_released: u64, timestamp: u64): u64
struct DaoTreasury<phantom DaoWitness: drop> has key, store {
    id: UID,
    coins: Bag,
    dao: ID,
}
struct FlashLoan<phantom DaoWitness, phantom CoinType> {
    amount: u64,
    fee: u64,
    type: TypeName
}
public fun dao<DaoWitness: drop>(treasury: &DaoTreasury<DaoWitness>): ID 
public fun balance<DaoWitness: drop, CoinType>(treasury: &DaoTreasury<DaoWitness>): u64
public fun donate<DaoWitness: drop, CoinType>(treasury: &mut DaoTreasury<DaoWitness>, token: Coin<CoinType>, ctx: &mut TxContext)
public fun transfer<DaoWitness: drop, CoinType, TransferCoin>(
    treasury: &mut DaoTreasury<DaoWitness>,
    _: &DaoAdmin<DaoWitness>,
    value: u64,
    ctx: &mut TxContext
): Coin<CoinType>
public fun transfer_linear_vesting_wallet<DaoWitness: drop, CoinType, TransferCoin>(
    treasury: &mut DaoTreasury<DaoWitness>,
    _: &DaoAdmin<DaoWitness>,
    c: &Clock,
    value: u64,
    start: u64,
    duration: u64,
    ctx: &mut TxContext    
): LinearWallet<CoinType>
public fun flash_loan<DaoWitness: drop, CoinType>(
    treasury: &mut DaoTreasury<DaoWitness>, 
    value: u64, 
    ctx: &mut TxContext
): (Coin<CoinType>, FlashLoan<DaoWitness, CoinType>)
public fun fee<DaoWitness: drop, CoinType>(flash_loan: &FlashLoan<DaoWitness, CoinType>): u64
public fun amount<DaoWitness: drop, CoinType>(flash_loan: &FlashLoan<DaoWitness, CoinType>): u64
public fun repay_flash_loan<DaoWitness: drop, CoinType>(
    treasury: &mut DaoTreasury<DaoWitness>, 
    flash_loan: FlashLoan<DaoWitness, CoinType>,
    token: Coin<CoinType>
)
Drawing
Proposal Life Cycle
Drawing
Vote Life Cycle

ASCII

A utility library to perate on ASCII strings.

Interface

contains

It checks if string a contains string b.

public fun contains(a: String, b: String): bool
  • @param a: A string.

  • @param b: Another string

  • @return bool. True if a contains b.

Aborts

  • b is longer than a.

append

Appends a and b

public fun append(a: String, b: String): String
  • @param a: The first subtring.

  • @param b: The second substring.

  • @return String. b os longer than a `a` + `b` => "hello" `append` "world" => "helloworld".

slice

Returns a [i, j) slice of the string starting at index i and going up to, but not including, index j.

public fun append(a: String, b: String): String
  • @param s: The string that will be sliced.

  • @param i: The first index of the substring.

  • @param j: The last index of the substring. This character is not included.

  • @return String. The substring.

Aborts

  • if j is greater than s.

  • if j is smaller than i.

into_char

It returns the Char at index i from string.

public fun into_char(string: &String, i: u64): Char
  • @param string: The string that contains the Char.

  • @param i: i The index of the Char we want to grab.

  • @return Char. The Char at index i.

Aborts

  • i is out of bounds

to_lower_case

It lowercases the string.

public fun to_lower_case(string: String): String
  • @param string: The string we wish to lowercase.

  • @return String. The lowercase string

to_upper_case

It uppercases the string.

public fun to_upper_case(string: String): String
  • @param string: The string we wish to lowercase.

  • @return String. The lowercase string

u128_to_string

Converts a u128 to its ascii::String decimal representation.

public fun u128_to_string(value: u128): String
  • @param value: A u128.

  • @return String. The string representation of value. E.g. 128 => "128".

u128_to_hex_string

Converts a u128 to its ascii::String hexadecimal representation.

public fun u128_to_hex_string(value: u128): String 
  • @param value: A u128.

  • @return String. The HEX string representation of value. E.g. 10 => "0xA".

u128_to_hex_string_to_fixed_length

Converts a u128 to its ascii::String hexadecimal representation with fixed length (in whole bytes). The returned String is 2 * length + 2(with '0x') in size.

public fun u128_to_hex_string_fixed_length(value: u128, length: u128): String
  • @param value: A u128.

  • @param length: length of the string.

  • @return String. The HEX string representation of value. E.g. 10 => "0xA".

bytes_to_hex_string

Converts a vector<u8> to its ascii::String hexadecimal representation.

public fun bytes_to_hex_string(bytes: vector<u8>): String
  • @param value A u128.

  • @return String. The HEX string representation of bytes. E.g. 0b1010 => "0x0A".

addr_into_string

Converts an address addr to its ascii::String representation. Addresses are 32 bytes, whereas the string-encoded address is 64 bytes. Outputted strings do not include the 0x prefix.

public fun addr_into_string(addr: address): String
  • @param addr: A 32-byte address.

  • @return String. The ascii::String representation of addr.

u8_to_ascii

Converts a u8 num to an ascii character.

public fun u8_to_ascii(num: u8): u8
  • @param num: decimal representation of an ASCII character.

  • @return u8. The ascii::String code for num.

ascii_to_u8

Converts an ASCII character to its decimal representation u8.

public fun ascii_to_u8(char: u8): u8
  • @param char: ASCII character.

  • @return u8. The decimal representation of char.

Comparator

A library to compare structs. BCS uses little-endian encoding for all integer types, so results might be unexpected.

Result

  struct Result has drop {
    inner: u8,
  }
  • inner - It will hold one of the following values: {SMALLER}, {EQUAL} or {GREATER}.

Interface

eq

It checks if the result of {compare} is EQUAL.

public fun eq(result: &Result): bool
  • @param result: This struct contains one of the following values: {SMALLER}, {EQUAL} or {GREATER}.

  • @return bool. True if it is EQUAL

lt

It checks if the result of {compare} is SMALLER.

public fun lt(result: &Result): bool
  • @param result: This struct contains one of the following values: {SMALLER}, {EQUAL} or {GREATER}.

  • @return bool. True if it is SMALLER

gt

It checks if the result of {compare} is GREATER.

public fun gt(result: &Result): bool
  • @param result: This struct contains one of the following values: {SMALLER}, {EQUAL} or {GREATER}.

  • @return bool. True if it is GREATER

lte

It checks if the result of {compare} is SMALLER or EQUAL.

public fun lte(result: &Result): bool
  • @param result: This struct contains one of the following values: {SMALLER}, {EQUAL} or {GREATER}.

  • @return bool. True if it is SMALLER or EQUAL.

gte

It checks if the result of {compare} is SMALLER or EQUAL.

public fun gte(result: &Result): bool
  • @param result: This struct contains one of the following values: {SMALLER}, {EQUAL} or {GREATER}.

  • @return bool. True if it is SMALLER or EQUAL.

compare

Compares two structs of type T. Performs a comparison of two types after BCS serialization.

public fun compare<T>(left: &T, right: &T): Result
  • @param left: A struct of type T.

  • @param right: A struct of type T.

  • @return Result. A struct that contains the following values: {SMALLER}, {EQUAL} or {GREATER}.

compare_u8_vector

Compares two bytes.

public fun compare_u8_vector(left: vector<u8>, right: vector<u8>): Result
  • @param left: A set of bytes.

  • @param right: A set of bytes.

  • @return Result. A struct that contains the following values: {SMALLER}, {EQUAL} or {GREATER}.

Merkle Proof

Allows users to verify Merkle Tree proofs. It is based on the OZ implementation. The tree and the proofs can be generated using https://github.com/merkletreejs/merkletreejs.

You should avoid using leaf values that are 64 bytes long prior to hashing.

Interface

verify

Returns true if a leaf can be proved to be a part of a Merkle tree defined by root.

public fun verify(
    proof: &vector<vector<u8>>,
    root: vector<u8>,
    leaf: vector<u8>
  ): bool
  • @param proof: The Merkle proof.

  • @param root: The root of Merkle Tree.

  • @param leaf: The leaf we wish to prove if it is part of the tree.

  • @return bool. If it is part of the Merkle tree.

verify_with_index

Returns true if a leaf can be proved to be a part of a Merkle tree defined by root. For this, a proof must be provided, containing sibling hashes on the branch from the leaf to the root of the tree. Each pair of leaves and each pair of pre-images are assumed to be sorted.

The index logic is from ENS token: https://etherscan.io/token/0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72#code

public fun verify_with_index(
    proof: &vector<vector<u8>>,
    root: vector<u8>,
    leaf: vector<u8>
): (bool, u256)
  • @param proof: The Merkle proof.

  • @param root: The root of Merkle Tree.

  • @param leaf: The leaf we wish to prove if it is part of the tree.

  • @return bool. If it is part of the Merkle tree.

  • @return u256. The index of the leaf.

Fixed Point Roll

A set of functions to operate over u64 numbers with 1e9 precision.

Interface

roll

It returns 1 ROLL - 1_000_000_000.

public fun roll(): u64
  • @return u64. 1e9

try_mul_down

It tries to x * y / 1_000_000_000 rounding down. It returns zero instead of throwing an overflow error.

public fun try_mul_down(x: u64, y: u64): (bool, u64)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x * y / 1_000_000_000.

try_mul_up

It tries to x * y / 1_000_000_000 rounding up. It returns zero instead of throwing an overflow error.

public fun try_mul_up(x: u64, y: u64): (bool, u64)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x * y / 1_000_000_000.

try_div_down

It tries to x * 1_000_000_000 / y rounding down. It returns zero instead of throwing an overflow error.

public fun try_div_down(x: u64, y: u64): (bool, u64)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x * 1_000_000_000 / y.

try_div_up

It tries to x * 1_000_000_000 / y rounding up. It returns zero instead of throwing an overflow error.

public fun try_div_up(x: u64, y: u64): (bool, u64)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x * 1_000_000_000 / y.

mul_down

x * y / 1_000_000_000 rounding down.

public fun mul_down(x: u64, y: u64): u64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x * y / 1_000_000_000.

Aborts

  • On overflow. If the result is over the maximum u256 number.

mul_up

x * y / 1_000_000_000 rounding up.

public fun mul_up(x: u64, y: u64): u64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x * y / 1_000_000_000.

Aborts

  • On overflow. If the result is over the maximum u256 number.

div_down

x * 1_000_000_000 / y rounding down.

public fun div_down(x: u64, y: u64): u64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x * 1_000_000_000 / y.

Aborts

  • On zero division.

div_up

x * 1_000_000_000 / y rounding up.

public fun div_up(x: u64, y: u64): u64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x * 1_000_000_000 / y.

Aborts

  • On zero division.

to_roll

It converts x precision to a ROLL, a number with a precision of 1e9.

public fun to_roll(x: u64, decimal_factor: u64): u64
  • @param x: The value to be converted.

  • @param decimal_factor: The current decimal scalar of x.

  • @return u64. The result of x * 1_000_000_000 / y.

Aborts

  • decimal_factor is zero.

Vectors

Utility functions for vectors.

Interface

find_upper_bound

Searches a sorted vec and returns the first index that contains a value greater or equal to element. If no such index exists (i.e. all values in the vector are strictly less than element), and the vector length is returned.

Time complexity O(log n).

public fun find_upper_bound(vec: vector<u64>, element: u64): u64
  • @param vec: The vector to be searched.

  • @param element: We check if there is a value higher than it in the vector.

  • @return u64. The index of the member that is larger than element. The length is returned if no member is found.

lt

Checks if a is smaller than b. E.g. x"123" < x"456".

public fun lt(a: vector<u8>, b: vector<u8>): bool
  • @param a: The first operand.

  • @param b: The second operand..

  • @return bool. If a is smaller than b.

Aborts

  • a and b have different lengths.

gt

Checks if a is larger than b. E.g. x"123" < x"456".

public fun gt(a: vector<u8>, b: vector<u8>): bool
  • @param a: The first operand.

  • @param b: The second operand..

  • @return bool. If a is larger than b.

Aborts

  • a and b have different lengths.

lte

Checks if a is smaller or equal to b. E.g. x"123" =< x"456".

public fun lte(a: vector<u8>, b: vector<u8>): bool
  • @param a: The first operand.

  • @param b: The second operand..

  • @return bool. If a is smaller or equal to b.

Aborts

  • a and b have different lengths.

gte

Checks if a is larger or equal to b. E.g. x"123" =< x"456".

public fun gte(a: vector<u8>, b: vector<u8>): bool 
  • @param a: The first operand.

  • @param b: The second operand..

  • @return bool. If a is larger or equal to b.

Aborts

  • a and b have different lengths.

ascending_insertion_sort

Sorts a a in ascending order. E.g. [342] => [234].

public fun ascending_insertion_sort(a: vector<u256>): vector<u256>
  • @param a: The vector to sort.

  • @return vector. Sorted a.

Aborts

  • a and b have different lengths.

descending_insertion_sort

Sorts a a in descending order. E.g. [342] => [432].

public fun descending_insertion_sort(a: vector<u256>): vector<u256>
  • @param a: The vector to sort.

  • @return vector. Sorted a.

Aborts

  • a and b have different lengths.

quick_sort

Sorts a values. E.g. [342] => [234].

This function mutates the original vector.

public fun quick_sort(values: &mut vector<u256>, left: u64, right: u64)
  • @param values: The vector to sort.

  • @param left: The smaller side of the pivot. Pass 0.

  • @param right: The larger side of the pivot. Pass vector::length - 1.

Fixed Point 64

A library to perform math operations over an unsigned integer with 64-bit precision. Any operation that results in a number larger than the maximum unsigned 128 bit, will be considered an overflow and throw.

Structs

FixedPoint64

struct FixedPoint64 has copy, drop, store { value: u128 }
  • value - The number.

Interface

value

It returns the raw u128 value.

public fun value(self: FixedPoint64): u128
  • @param self: A FixedPoint64

  • @return u128. The raw u128 value.

from

Creates a FixedPoint64 from a u128 number. It scales the number.

public fun from(value: u128): FixedPoint64
  • @param value: A u128 number.

  • @return A FixedPoint64. calculated by right shifting - value << 64.

Aborts

  • The left-shifted value is larger than MAX_U128.

from_raw_value

Creates a FixedPoint64 from a u128 value. It does not scale the value.

public fun from_raw_value(value: u128): FixedPoint64
  • @param value: A u128 number.

  • @return FixedPoint64. It wraps the u128.

from_rational

Creates a FixedPoint64 from a rational number specified by a numerator anddenominator.

0.0125 will round down to 0.012 instead of up to 0.013.

public fun from_rational(numerator: u128, denominator: u128): FixedPoint64
  • @param numerator: The numerator of the rational number.

  • @param denominator: The denominator of the rational number.

  • @return FixedPoint64. A FixedPoint64 from (numerator << 64) / denominator.

Aborts

  • if the denominator is zero

  • if the numerator / denominator is zero

  • if the numerator is nonzero and the ratio is not in the range 2^-64 .. 2^64-1

to_u128

Converts a FixedPoint64 into a u128 number to the closest integer.

public fun to_u128(self: FixedPoint64): u128
  • @param self. A FixedPoint64.

  • @return u128.

to_u128_down

Converts a FixedPoint64 into a u128 number rounding down.

public fun to_u128_down(self: FixedPoint64): u128
  • @param self. A FixedPoint64.

  • @return u128.

to_u128_up

Converts a FixedPoint64 into a u128 number rounding up.

public fun to_u128_up(self: FixedPoint64): u128
  • @param self. A FixedPoint64.

  • @return u128.

is_zero

Checks if self is zero.

public fun is_zero(self: FixedPoint64): bool
  • @param self. A FixedPoint64.

  • @return bool. If the self.value is zero.

eq

Checks if x is equal to y.

public fun eq(x: FixedPoint64, y: FixedPoint64): bool
  • @param x: A FixedPoint64.

  • @param y: A FixedPoint64.

  • @return bool. If the values are equal.

lt

Checks if x is smaller or equal to y.

public fun lt(x: FixedPoint64, y: FixedPoint64): bool
  • @param x: A FixedPoint64.

  • @param y: A FixedPoint64.

  • @return bool. If x is smaller than y.

gt

Checks if x is bigger than y.

public fun gt(x: FixedPoint64, y: FixedPoint64): bool
  • @param x: A FixedPoint64.

  • @param y: A FixedPoint64.

  • @return bool. If x is bigger or equal to y.

lte

Checks if x is smaller or equal to y.

public fun lte(x: FixedPoint64, y: FixedPoint64): bool
  • @param x: A FixedPoint64.

  • @param y: A FixedPoint64.

  • @return bool. If x is smaller or equal to y.

gte

Checks if x is bigger or equal to y.

public fun gte(x: FixedPoint64, y: FixedPoint64): bool
  • @param x: A FixedPoint64.

  • @param y: A FixedPoint64.

  • @return bool. If x is bigger or equal to y.

max

It returns the larger of the two arguments.

public fun max(x: FixedPoint64, y: FixedPoint64): FixedPoint64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return FixedPoint64. The larger argument.

min

It returns the smaller of the two arguments.

public fun min(x: FixedPoint64, y: FixedPoint64): FixedPoint64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return FixedPoint64. The smaller argument.

sub

It returns x - y.

public fun sub(x: FixedPoint64, y: FixedPoint64): FixedPoint64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return FixedPoint64. The result of x - y.

Aborts

  • y > x

add

It returns x + y.

public fun add(x: FixedPoint64, y: FixedPoint64): FixedPoint64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return FixedPoint64. The result of x + y.

Aborts

  • y + x >= MAX_U128

mul

It returns x * y.

Use {mul_128} if you think the values can overflow.

public fun mul(x: FixedPoint64, y: FixedPoint64): FixedPoint64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return FixedPoint64. The result of x * y.

Aborts

  • inner values overflow.

div

It returns x / y.

public fun div(x: FixedPoint64, y: FixedPoint64): FixedPoint64
  • @param x: The first operand.

  • @param y: The second operand.

  • @return FixedPoint64. The result of x / y.

Aborts

  • if y is zero.

mul_div

Specialized function for x * y / z that omits intermediate shifting.

public fun mul_div(x: FixedPoint64, y: FixedPoint64, z: FixedPoint64): FixedPoint64
  • @param x: A FixedPoint64.

  • @param y: A FixedPoint64.

  • @param z: The third operand.

  • @return FixedPoint64. The result of x * y / z.

Aborts

  • if z is zero.

mul_u128

It returns x * y.It multiplies a u128 number with a FixedPoint64. It truncates the fractional part of the product. E.g. - 9 * 0.333 = 2.

public fun mul_u128(x: u128, y: FixedPoint64): u128
  • @param x: A FixedPoint64.

  • @param y: A FixedPoint64.

  • @return u128. The result of x * y without the 64-bit precision.

Aborts

  • if the result is larger or equal to MAX_U128.

div_down_u128

It returns numerator / denominator rounded down. It divides a FixedPoint64 by a u128 number.

public fun div_down_u128(numerator: u128, denominator: FixedPoint64): u128
  • @param numerator: The first operand, a u128 number.

  • @param denominator: The first operand, a u128 number.

  • @return u128. The result of numerator / denominator without the 64-bit precision.

Aborts

  • if the result is larger or equal to MAX_U128.

  • if the denominator is zero.

div_up_u128

It returns numerator / denominator rounded up. It divides a FixedPoint64 by a u128 number.

public fun div_up_u128(numerator: u128, denominator: FixedPoint64): u128
  • @param numerator: The first operand, a u128 number.

  • @param denominator: The first operand, a u128 number.

  • @return u128. The result of numerator / denominator without the 64-bit precision.

Aborts

  • if the result is larger or equal to MAX_U128.

  • if the denominator is zero.

pow

It returns base ** exponent.

public fun pow(base: FixedPoint64, exponent: u64): FixedPoint64
  • @param base: The base.

  • @param exponent: The exponent.

  • @return FixedPoint64. The result of base ** exponent.

Aborts

  • if the end result is higher than MAX_U128.

sqrt

Square root of x.

public fun sqrt(x: FixedPoint64): FixedPoint64
  • @param x: The operand.

  • @return FixedPoint64. The result of the square root.

exp

It performs e^x. Exponent function with a precision of 9 digits.

public fun exp(x: FixedPoint64): FixedPoint64
  • @param x: The operand.

  • @return FixedPoint64. The result of e^x.

Fixed Point Wad

A set of functions to operate over u256 numbers with 1e18 precision. It emulates the decimal precision of ERC20 to port some of their advanced math operations such as exp and exp and ln.

Interface

wad

It returns 1 WAD - 1_000_000_000_000_000_000.

public fun wad(): u256
  • @return u64. 1e18

try_mul_down

It tries to x * y / 1_000_000_000_000_000_000 rounding down. It returns zero instead of throwing an overflow error.

public fun try_mul_down(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x * y / 1_000_000_000_000_000_000.

try_mul_up

It tries to x * y / 1_000_000_000_000_000_000 rounding up. It returns zero instead of throwing an overflow error.

public fun try_mul_up(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x * y / 1_000_000_000_000_000_000.

try_div_down

It tries to x * 1_000_000_000_000_000_000 / y rounding down. It returns zero instead of throwing an overflow error.

public fun try_div_down(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x * 1_000_000_000_000_000_000 / y.

try_div_up

It tries to x * 1_000_000_000_000_000_000 / y rounding up. It returns zero instead of throwing an overflow error.

public fun try_div_up(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x * 1_000_000_000_000_000_000 / y.

mul_down

x * y / 1_000_000_000_000_000_000 rounding down.

public fun mul_down(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The result of x * y / 1_000_000_000_000_000_000.

Aborts

  • On overflow. If the result is over the maximum u256 number.

mul_up

x * y / 1_000_000_000_000_000_000 rounding up.

public fun mul_up(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The result of x * y / 1_000_000_000_000_000_000.

Aborts

  • On overflow. If the result is over the maximum u256 number.

div_down

x * 1_000_000_000_000_000_000 / y rounding down.

public fun div_down(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The result of x * 1_000_000_000_000_000_000 / y.

Aborts

  • On zero division.

div_up

x * 1_000_000_000_000_000_000 / y rounding up.

public fun div_up(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The result of x * 1_000_000_000_000_000_000 / y.

Aborts

  • On zero division.

to_wad

It converts x precision to a , a number with a precision of 1e18.

public fun to_wad(x: u256, decimal_factor: u256): u256
  • @param x: The value to be converted.

  • @param decimal_factor: The current decimal scalar of x.

  • @return u64. The result of x * 1_000_000_000_000_000_000 / y.

Aborts

  • decimal_factor is zero.

exp

It calculates e^x.

All credits to Remco Bloemen and more information here: https://xn--2-umb.com/22/exp-ln/

public fun exp(x: Int): Int
  • @param x: The exponent.

  • @return Int. The result of e^x.

Aborts

  • x is larger than 135305999368893231589.

ln

It calculates ln(x).

All credits to Remco Bloemen and more information here: https://xn--2-umb.com/22/exp-ln/

public fun ln(x: Int): Int
  • @param x: The operand.

  • @return Int. The result of ln(x).

Aborts

  • x is negative or zero.

CLAMM🐚

Concentrated Liquidity Automated Market Maker

Interest Protocol CLAMM is a decentralized exchange with the following features:

  • Volatile Curve: These pools track the prices of the assets via internal oracles using an exponential moving average. It concentrates the liquidity around that price.

  • Public Good: Interest Protocol does not have access to the swap fees. They are all in control of the deployer of the pool. This makes the CLAMM into a public good. It acts as a venue for projects to own the revenue from their protocol coin volume.

  • Passive Liquidity Management: UniswapV3 requires liquidity providers to actively manage their liquidity to capture fees and reduce impermanent loss. The Interest CLAMM moves the liquidity around automatically. This facilitates liquidity provision for everyone.

  • One Sided Liquidity: Liquidity providers are not required to provide or remove both coins in a CLAMM pool. They are free to provide their preferred coin.

  • LpCoins: Liquidity in the CLAMM is represed by Coins instead of NFTs. This make sit more composable in DeFi because of its fungibility. You can easily price them by checking the liquidity in the DEX and vistual price.

  • Multi-coin Pools: CLAMM pools support more than 2 coins. This allows for more exotic and concentrated pairs.

Stable Curve: A bonding curve specially designed for correlated assets. It combines the constant product invariant (k = x * y) with the constant sum invariant (k = x + y) via an amplifier to flatten the curve in the middle. You can read more about it .

Hooks: Inspired by , Interest Protocol CLAMM implements pool policies. Deployers can customize their pools by implementing custom computation before or after a swap or liquidity position change. This extends the pools to support a myriad of applications such as ERC404, fee on swap, limit orders, custom oracles, etc...

here
UniswapV4 hooks

Math256

Structs

Constants

const MAX_U256: u256 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

Interface

try_add

It tries to perform x + y. Checks for overflow.

public fun try_add(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x + y. If it fails, it will be 0.

try_sub

It tries to perform x - y. Checks for underflow.

public fun try_sub(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x - y. If it fails, it will be 0.

try_mul

It tries to perform x * y.

public fun try_mul(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x * y. If it fails, it will be 0.

try_div_down

It tries to perform x / y rounding down.

public fun try_div_down(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x / y. If it fails, it will be 0.

try_div_up

It tries to perform x / y rounding up.

public fun try_div_up(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u256. The result of x / y. If it fails, it will be 0.

try_mul_div_down

It tries to perform x * y / z rounding down. Checks for zero division and overflow.

public fun try_mul_div_down(x: u256, y: u256, z: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u256. The result of x * y / z. If it fails, it will be 0.

try_mul_div_up

It tries to perform x * y / z rounding up.

public fun try_mul_div_up(x: u256, y: u256, z: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u256. The result of x * y / z. If it fails, it will be 0.

try_mod

It tries to perform x % y.

public fun try_mod(x: u256, y: u256): (bool, u256)
  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u256. The result of x % y. If it fails, it will be 0.

mul

It performs x * y.

public fun mul(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The result of x * y.

div_down

It performs x / y rounding down.

public fun div_down(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The result of x / y.

Abort

  • It will throw on zero division.

div_up

It performs x / y rounding up.

public fun div_up(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The result of x / y.

Abort

  • It will throw on zero division.

mul_div_down

It performs x * y / z rounding down.

public fun mul_div_down(x: u256, y: u256, z: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor

  • @return u256. The result of x * y / z.

mul_div_up

It performs x * y / z rounding up.

public fun mul_div_up(x: u256, y: u256, z: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor

  • @return u256. The result of x * y / z.

min

It returns the lowest number.

public fun min(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The lowest number.

max

It returns the largest number.

public fun max(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The largest number.

clamp

Clamps x between the range of [lower, upper]

public fun clamp(x: u256, lower: u256, upper: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The clamped x.

diff

Performs |x - y|.

public fun diff(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. The difference.

pow

Performs n^e.

public fun pow(n: u256, e: u256): u256
  • @param n: The base.

  • @param e: The exponent.

  • @return u256. The result of n^e.

sum

Adds all x in nums in a vector.

public fun sum(nums: vector<u256>): u256
  • @param nums: A vector of numbers.

  • @return u256. The sum.

average

It returns the average between two numbers (x + y) / 2.

It does not overflow.

public fun average(x: u256, y: u256): u256
  • @param x: The first operand.

  • @param y: The second operand.

  • @return u256. (x + y) / 2.

average_vector

Calculates the average of the vector of numbers sum of vector/length of vector.

public fun average_vector(nums: vector<u256>): u256
  • @param nums: A vector of numbers.

  • @return u256. The average.

sqrt_down

Returns the square root of x number. If the number is not a perfect square, the x is rounded down.

public fun sqrt_down(x: u256): u256
  • @param a: The operand.

  • @return u256. The square root of x rounding down.

sqrt_up

Returns the square root of x number. If the number is not a perfect square, the x is rounded up.

public fun sqrt_up(x: u256): u256
  • @param a: The operand.

  • @return u256. The square root of x rounding up.

log2_down

Returns the log2(x) rounding down.

public fun log2_down(x: u256): u8
  • @param x: The operand.

  • @return u8. Log2(x).

log2_up

Returns the log2(x) rounding up.

public fun log2_up(x: u256): u16
  • @param x: The operand.

  • @return u16. Log2(x).

log10_down

Returns the log10(x) rounding down.

public fun log10_down(x: u256): u8
  • @param x: The operand.

  • @return u8. Log10(x)

log10_up

Returns the log10(x) rounding up.

public fun log10_up(x: u256): u8
  • @param x: The operand.

  • @return u8. Log10(x)

log256_down

Returns the log256(x) rounding down.

public fun log256_down(x: u256): u8
  • @param x: The operand.

  • @return u8. Log256(x).

log256_up

Returns the log256(x) rounding up.

public fun log256_up(x: u256): u8
  • @param x: The operand.

  • @return u8. Log256(x).

Hooks

Design

Hooks follow the same design principle as Sui's Kiosk transfer policy. It allows developers to enforce rules to pools. The rules are completed by calling the rule's module and collecting its witness. Rules can be anything from custom oracles to fee on swap.

Hooks

The CLAMM supports 8 hooks:

  • Start Swap: This hook must be completed before a swap transaction.

  • Finish Swap: A swap transaction must fulfill this hook to finish.

  • Start Add Liquidity: This hook must be completed before a user adds liquidity.

  • Finish Add Liquidity: A transaction to add liquidity must fulfill this hook to finish.

  • Start Remove Liquidity: This hook must be completed before a user removes liquidity.

  • Finish Remove Liquidity: A transaction to remove liquidity must fulfill this hook to finish.

  • Start Donate: This hook must be completed before a swap transaction.

  • Finish Donate: A swap transaction must fulfill this hook to finish.

Pools are not required to have hooks and a pool can have a Start Swap hook without a Finish Swap hook. Hooks are set at deployment and cannot be changed afterwards.

Examples

We will provide a set of standard hooks that will be automatically resolved via the SDK. Please refer to them on how to use your own hooks!

https://github.com/interest-protocol/hooks

Int

A library to convert unsigned integers to signed integers using two's complement. It contains basic arithmetic operations for signed integers.

Uses arithmetic shr and shl for negative numbers

Structs

Int

struct Int has copy, drop, store {
    value: u256
 }
  • value - The number.

const EQUAL: u8 = 0;

const LESS_THAN: u8 = 1;

const GREATER_THAN: u8 = 2;

Interface

value

It returns the inner value inside self.

public fun value(self: Int): u256
  • @param self: The Int struct.

  • @return u256.

zero

It creates a zero Int.

public fun zero(): Int
  • @return Int. The wrapped value.

one

It creates a one Int.

public fun one(): Int
  • @return Int. The wrapped value.

max

It creates the largest possible Int.

Maximum number is : 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

public fun max(): Int
  • @return Int.

from_u8

It wraps a u8 value into an Int.

public fun from_u8(value: u8): Int
  • @param value: The u8 value to wrap

  • @return Int. The wrapped value

from_u16

It wraps a u16 value into an Int.

public fun from_u16(value: u16): Int
  • @param value: The u16 value to wrap

  • @return Int. The wrapped value

from_u32

It wraps a u32 value into an Int.

public fun from_u32(value: u32): Int
  • @param value: The u32 value to wrap

  • @return Int. The wrapped value

from_u64

It wraps a u64 value into an Int.

public fun from_u64(value: u64): Int
  • @param value: The u64 value to wrap

  • @return Int. The wrapped value

from_u128

It wraps a u128 value into an Int.

public fun from_u128(value: u128): Int
  • @param value: The u128 value to wrap

  • @return Int. The wrapped value

from_u256

It wraps a u128 value into an Int.

public fun from_u256(value: u256): Int
  • @param value: The u256 value to wrap

  • @return Int. The wrapped value

Abort

  • if value is larger than 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF.

neg_from_u8

It wraps a u8 value into an Int and negates it.

public fun neg_from_u8(value: u8): Int
  • @param value: The u16 value to wrap

  • @return Int. The wrapped value

neg_from_u16

It wraps a u16 value into an Int and negates it.

public fun neg_from_u16(value: u16): Int
  • @param value: The u16 value to wrap

  • @return Int. The wrapped value

neg_from_u32

It wraps a u32 value into an Int and negates it.

public fun neg_from_u32(value: u32): Int
  • @param value: The u32 value to wrap

  • @return Int. The wrapped value

neg_from_u64

It wraps a u64 value into an Int and negates it.

public fun neg_from_u64(value: u64): Int
  • @param value: The u64 value to wrap

  • @return Int. The wrapped value

neg_from_u128

It wraps a u128 value into an Int and negates it.

public fun neg_from_u128(value: u128): Int
  • @param value: The u128 value to wrap

  • @return Int. The wrapped value

neg_from_u256

It wraps a u256 value into an Int and negates it.

public fun neg_from_u256(value: u256): Int
  • @param value: The u256 value to wrap

  • @return Int. The wrapped value

to_u8

It unwraps the value inside self and casts it to u8.

public fun to_u8(self: Int): u8
  • @param self: The Int struct.

  • @return u8. The inner value cast to u8.

Abort

  • self.value is negative

to_u16

It unwraps the value inside self and casts it to u16.

public fun to_u16(self: Int): u16
  • @param self: The Int struct.

  • @return u16. The inner value cast to u16.

Abort

  • self.value is negative

to_u32

It unwraps the value inside self and casts it to u32.

public fun to_u32(self: Int): u32
  • @param self: The Int struct.

  • @return u32. The inner value cast to u32.

Abort

  • self.value is negative

to_u64

It unwraps the value inside self and casts it to u64.

public fun to_u64(self: Int): u64
  • @param self: The Int struct.

  • @return u64. The inner value cast to u64.

Abort

  • self.value is negative

to_u128

It unwraps the value inside self and casts it to u128.

public fun to_u128(self: Int): u128
  • @param self: The Int struct.

  • @return u128. The inner value cast to u128.

Abort

  • self.value is negative

to_u256

It unwraps the value inside self and casts it to u256.

public fun to_u256(self: Int): u256
  • @param self: The Int struct.

  • @return u128. The inner value cast to u256.

Abort

  • self.value is negative

truncate_to_u8

It unwraps the value inside self and truncates it to u8.

public fun truncate_to_u8(self: Int): u8
  • @param self: The Int struct.

  • @return u8. The inner value is truncated to u8.

truncate_to_u16

It unwraps the value inside self and truncates it to u16.

public fun truncate_to_u16(self: Int): u16
  • @param self: The Int struct.

  • @return u8. The inner value is truncated to u16.

truncate_to_u32

It unwraps the value inside self and truncates it to u16.

public fun truncate_to_u32(self: Int): u32
  • @param self: The Int struct.

  • @return u8. The inner value is truncated to u32.

truncate_to_u64

It unwraps the value inside self and truncates it to u64.

public fun truncate_to_u64(self: Int): u64
  • @param self: The Int struct.

  • @return u8. The inner value is truncated to u64.

truncate_to_u128

It unwraps the value inside self and truncates it to u128.

public fun truncate_to_u128(self: Int): u128
  • @param self: The Int struct.

  • @return u8. The inner value is truncated to u128.

flip

It flips the sign of self.

public fun flip(self: Int): Int
  • @param self: The Int struct.

  • @return Int. The returned Int will have its signed flipped.

abs

It returns the absolute of an Int.

public fun abs(self: Int): Int
  • @param self: The Int struct.

  • @return Int. The absolute.

is_neg

It checks if self is negative.

public fun is_neg(self: Int): bool
  • @param self: The Int struct.

  • @return bool.

is_zero

It checks if self is zero.

public fun is_zero(self: Int): bool
  • @param self: The Int struct.

  • @return bool.

is_positive

It checks if self is positive.

public fun is_positive(self: Int): bool
  • @param self: The Int struct.

  • @return bool.

compare

It compares a and b.

public fun compare(a: Int, b: Int): u8
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return 0. a == b.

  • @return 1. a < b.

  • @return 2. a > b.

eq

It checks if a and b are equal.

public fun eq(a: Int, b: Int): bool
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return bool.

lt

It checks if a < b.

public fun lt(a: Int, b: Int): bool
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return bool.

lte

It checks if a <= b.

public fun lte(a: Int, b: Int): bool
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return bool.

gt

It checks if a > b.

public fun gt(a: Int, b: Int): bool
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return bool.

gte

It checks if a >= b.

public fun gte(a: Int, b: Int): bool
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return bool.

add

It checks if a >= b.

public fun add(a: Int, b: Int): Int
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return Int. The result of a + b.

sub

It performs a - b.

public fun sub(a: Int, b: Int): Int
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return Int. The result of a - b.

mul

It performs a * b.

public fun mul(a: Int, b: Int): Int
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return Int. The result of a * b.

div_down

It performs a / b rounding down.

public fun div_down(a: Int, b: Int): Int
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return Int. The result of a / b rounding down.

div_up

It performs a / b rounding up.

public fun div_up(a: Int, b: Int): Int
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return Int. The result of a / b rounding up.

mod

It performs a % b.

public fun mod(a: Int, b: Int): Int
  • @param a: An Int struct.

  • @param b: An Int struct.

  • @return Int. The result of a % b.

pow

It performs base ** exponent.

public fun pow(base: Int, exponent: u256): Int
  • @param base: An Int struct.

  • @param exponent: The exponent.

  • @return Int. The result of base ** exponent.

shr

It performs self >> rhs.

public fun shr(self: Int, rhs: u8): Int
  • @param self: An Int struct.

  • @param rhs: The value to right-hand shift.

  • @return Int. The result of self >> rhs.

shl

It performs self << lhs.

public fun shl(self: Int, lhs: u8): Int
  • @param self: An Int struct.

  • @param lhs: The value to right-hand shift.

  • @return Int. The result of self << lhs.

or

It performs a | b.

public fun or(a: Int, b: Int): Int
  • @param a: The first operand.

  • @param b: The second operand.

  • @return Int. The result of a | b.

and

It performs a & b.

public fun and(a: Int, b: Int): Int
  • @param a: The first operand.

  • @param b: The second operand.

  • @return Int. The result of a & b.

Math64

A set of functions to operate over u64 numbers.

Beware that some operations throw on overflow and underflows.

Structs

Constants

Interface

wrapping_add

It performs x + y.

It will wrap around the MAX_U64. MAX_U64 + 1 = 0.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x + y.

wrapping_sub

It performs x - y.

It will wrap around zero. 0 - 1 = MAX_U64.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x - y.

wrapping_mul

It performs x * y.

It will wrap around. MAX_U64 * MAX_U64 = 0.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x * y.

try_add

It tries to perform x + y. Checks for overflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x + y. If it fails, it will be 0.

try_sub

It tries to perform x - y. Checks for underflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x - y. If it fails, it will be 0.

try_mul

It tries to perform x * y.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x * y. If it fails, it will be 0.

try_div_down

It tries to perform x / y rounding down.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x / y. If it fails, it will be 0.

try_div_up

It tries to perform x / y rounding up.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u64. The result of x / y. If it fails, it will be 0.

try_mul_div_down

It tries to perform x * y / z rounding down. Checks for zero division and overflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u64. The result of x * y / z. If it fails, it will be 0.

try_mul_div_up

It tries to perform x * y / z rounding up. Checks for zero division and overflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u64. The result of x * y / z. If it fails, it will be 0.

try_mod

It tries to perform x % y.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u64. The result of x % y. If it fails, it will be 0.

mul

It performs x * y.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x * y.

div_down

It performs x / y rounding down.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x / y.

div_up

It performs x / y rounding up.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The result of x / y.

mul_div_down

It performs x * y / z rounding down.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor

  • @return u64. The result of x * y / z.

mul_div_up

It performs x * y / z rounding up.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor

  • @return u64. The result of x * y / z.

min

It returns the lowest number.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The lowest number.

max

It returns the largest number.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The largest number.

clamp

Clamps x between the range of [lower, upper]

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The clamped x.

diff

Performs |x - y|.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. The difference.

pow

Performs n^e.

  • @param n: The base.

  • @param e: The exponent.

  • @return u128. The result of n^e.

sum

Adds all x in nums in a vector.

  • @param nums: A vector of numbers.

  • @return u64. The sum.

average

It returns the average between two numbers (x + y) / 2.

It does not overflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u64. (x + y) / 2.

average_vector

Calculates the average of the vector of numbers sum of vector/length of vector.

  • @param nums: A vector of numbers.

  • @return u64. The average.

sqrt_down

Returns the square root of x number. If the number is not a perfect square, the x is rounded down.

  • @param a: The operand.

  • @return u64. The square root of x rounding down.

sqrt_up

Returns the square root of x number. If the number is not a perfect square, the x is rounded up.

  • @param a: The operand.

  • @return u64. The square root of x rounding up.

log2_down

Returns the log2(x) rounding down.

  • @param x: The operand.

  • @return u8. Log2(x).

log2_up

Returns the log2(x) rounding up.

  • @param x: The operand.

  • @return u16. Log2(x).

log10_down

Returns the log10(x) rounding down.

  • @param x: The operand.

  • @return u8. Log10(x)

log10_up

Returns the log10(x) rounding up.

  • @param x: The operand.

  • @return u8. Log10(x)

log256_down

Returns the log256(x) rounding down.

  • @param x: The operand.

  • @return u8. Log256(x).

log256_up

Returns the log256(x) rounding up.

  • @param x: The operand.

  • @return u8. Log256(x).

Math128

A set of functions to operate over u128 numbers.

Beware that some operations throw on overflow and underflows.

Structs

Constants

Interface

try_add

It tries to perform x + y. Checks for overflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u128. The result of x + y. If it fails, it will be 0.

try_sub

It tries to perform x - y. Checks for underflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u128. The result of x - y. If it fails, it will be 0.

try_mul

It tries to perform x * y.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u128. The result of x * y. If it fails, it will be 0.

try_div_down

It tries to perform x / y rounding down.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u128. The result of x / y. If it fails, it will be 0.

try_div_up

It tries to perform x / y rounding up.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return bool. If the operation was successful.

  • @return u128. The result of x / y. If it fails, it will be 0.

try_mul_div_down

It tries to perform x * y / z rounding down. Checks for zero division and overflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u128. The result of x * y / z. If it fails, it will be 0.

try_mul_div_up

It tries to perform x * y / z rounding up. Checks for zero division and overflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u128. The result of x * y / z. If it fails, it will be 0.

try_mod

It tries to perform x % y.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor.

  • @return bool. If the operation was successful.

  • @return u128. The result of x % y. If it fails, it will be 0.

mul

It performs x * y.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u128. The result of x * y.

div_down

It performs x / y rounding down.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u128. The result of x / y.

div_up

It performs x / y rounding up.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u128. The result of x / y.

mul_div_down

It performs x * y / z rounding down.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor

  • @return u128. The result of x * y / z.

mul_div_up

It performs x * y / z rounding up.

  • @param x: The first operand.

  • @param y: The second operand.

  • @param z: The divisor

  • @return u128. The result of x * y / z.

min

It returns the lowest number.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u128. The lowest number.

max

It returns the largest number.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u128. The largest number.

clamp

Clamps x between the range of [lower, upper]

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u128. The clamped x.

diff

Performs |x - y|.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u128. The difference.

pow

Performs n^e.

  • @param n: The base.

  • @param e: The exponent.

  • @return u128. The result of n^e.

sum

Adds all x in nums in a vector.

  • @param nums: A vector of numbers.

  • @return u256. The sum.

average

It returns the average between two numbers (x + y) / 2.

It does not overflow.

  • @param x: The first operand.

  • @param y: The second operand.

  • @return u128. (x + y) / 2.

average_vector

Calculates the average of the vector of numbers sum of vector/length of vector.

  • @param nums: A vector of numbers.

  • @return u128. The average.

sqrt_down

Returns the square root of x number. If the number is not a perfect square, the x is rounded down.

  • @param a: The operand.

  • @return u128. The square root of x rounding down.

sqrt_up

Returns the square root of x number. If the number is not a perfect square, the x is rounded up.

  • @param a: The operand.

  • @return u128. The square root of x rounding up.

log2_down

Returns the log2(x) rounding down.

  • @param x: The operand.

  • @return u8. Log2(x).

log2_up

Returns the log2(x) rounding up.

  • @param x: The operand.

  • @return u16. Log2(x).

log10_down

Returns the log10(x) rounding down.

  • @param x: The operand.

  • @return u8. Log10(x)

log10_up

Returns the log10(x) rounding up.

  • @param x: The operand.

  • @return u8. Log10(x)

log256_down

Returns the log256(x) rounding down.

  • @param x: The operand.

  • @return u8. Log256(x).

log256_up

Returns the log256(x) rounding up.

  • @param x: The operand.

  • @return u8. Log256(x).

Whitepapers

Glossary

APR (Annual Percent Rate): refers to a yearly interest generated by the sum charged to borrowers or paid to investors. It is not compounded, which is why it is always lower than the APY.

APY: it is the APR but with compounding effects into consideration. It is also called the real returns.

Bridge: An application that allows a token to be transferred between two blockchains.

Collateral: a token used to secure a loan. It provides a safety net to the lender.

Cross-chain: refers to applications or functionalities that involve two or more blockchains. E.g., in Interest Protocol a user will be able to provide collateral in Ethereum and borrow in BSC.

DApp: Decentralized application.

DEX: Decentralized exchange. An automated broker to trade ERC20 tokens.

ERC20: It is the interface of all cryptocurrencies issued in EVM blockchains. It is what allows tokens to be transferred and work with DApps.

Farm: A contract that rewards a depositor a token as long as he deposits a token on it. E.g., it is usually used for a way to pay users that deposit LP Tokens.

Finality: How long a user must wait to consider the transaction confirmed.

Keepers: An automated system to call contract functions. It is used for maintenance, such as maintaining the right leverage amount in the Dinero Venus Vault.

Lending Protocol: A DApp that facilitates loans between users.

Liquidation: When a loan is underwater, a third party can close the position by repaying the loan to the lender using a portion of the collateral deposited by the borrower. It usually comes with a penalty fee for the borrower.

LP (Token): Liquidity provider tokens are receipt tokens given for users who deposit 2 tokens in DEXs, thus providing a swap market for other users. E.g., when a user deposits BNB/ETH in PCS. He is giving liquidity for other users to trade BNB and ETH. In exchange, PCS gives them LP Tokens that represent his/her deposit.

LTV (Loan-to-value-ratio): Amount borrowed divided by the collateral supplied in USD.

MasterChef: Famous multi-asset staking contract popularized by Sushi Swap.

Maturity Date: refers to the date that a loan must be repaid to avoid penalties.

NFT: Non-fungible token. They are unique tokens.

Oracle: A contract that is able to collect data from the outside world to be used by DApps inside the blockchain. The most famous oracle network is Chainlink.

Pair Lending Market: A lending market consisting of two cryptocurrencies. E.g., In the case of Dinero markets, one is used for collateral and the other for borrows. But in other designs, both of them can be used as collateral and borrows.

PCS: Pancake Swap. The leading DEX in Binance Smart Chain.

Pool: refers to a contract that accepts an ERC20 token and rewards for another token. It is similar to a farm but it is meant for non LP tokens. It is usually to incentivize holding or for marketing purposes. E.g., in PCS, a user can deposit Cake to earn more Cake.

Over-collateralized Loans: Unlike bank or credit loans, in which credit scores and other factors determine how much one can borrow, over-collateralized allow borrowers to borrow a percentage (the LTV - always below 100%) equivalent to their collateral. They allow borrowers to pursue long/short investment positions or attain quick liquidity without losing their portfolio positions.

P2P (Peer-to-Peer): A contract that connects a user directly to another user. Most lending schemas involve a user to interact with many users via pools. P2P has no pool or other intermediary in the middle. It purely acts as a way to enforce the agreed terms.

Rebase Token: A cryptocurrency that has an elastic supply. It can reduce or increase the balance of every user based on an algorithm. It is usually used to reward users or used to artificially increase the USD value per token.

Solvent: Having assets in excess of liabilities; Being able to pay one's debts.

Stablecoin: A cryptocurrency that is pegged to a FIAT currency, usually the American Dollar, USD.

Staking: The act of depositing a token in a contract to earn a bonus. It can be voting power, a token, etc... It is usually used when a user deposits in a pool and the term farming is used when a user deposits in a farm.

Supply (Lending): It is the act of depositing tokens in a Lending Protocol to be lent out to other users for a fee.

TPS: Transactions per second. A blockchain speed must take into account the TPS and finality.

TWAP (Time-Weighted Average Price): is an asset's average price over a predetermined period of time. They are an effective measure to prevent price manipulations.

TX: Transaction. It is anything that can change the blockchain state.

Underwater Position: A position in which the LTV is above the maximum LTV of the market. It happens when the collateral price depreciates and makes the position open for liquidation.

Vault: A contract that applies an investment strategy to funds collected from users. It lowers investment costs by distributing the transaction costs among all users and requires no active maintenance by depositors to execute the strategy.

vToken: A rebase token that represents an amount of underlying Token in Venus. The name was borrowed from Compound that uses cEther. E.g., vBTC represents an amount of BTC a user has supplied to Venus.

Wrapped Token: A token that holds another token (the wrapped token) and provides extra functionalities to interact with it. The most popular use case is to wrap a blockchain's native currencies such as ETH and BNB to give them ERC20 functionalities to interact with DApps easily.

IPX: Interest Protocol token, a token that is rewarded to liquidity providers to ensure that our DEX has enough liquidity to operate.

EVM: Ethereum Virtual Machine. Learn more about it .

EIP: Ethereum Improvement Proposals. Learn more about it .

Isolated Markets: Protocols like use one single pool, which means that any collateral can be used to borrow any asset in the pool. In an isolated architecture, the protocol consists of many pools. Therefore, Collateral A on Pool A cannot be used to borrow assets in Pool B; thus, it isolates Collateral A risk to Pool A, keeping pool B unexposed.

Mantissa: The number of significant digits to represent the quantity of a value. Learn more about it .

Synthetic: A cryptocurrency that pegs its value to a real-world asset through clever financial incentives. E.g., mTSLA issued by pegs to 1 share of Tesla Stock.

const MAX_U64: u256 = 18446744073709551615;
public fun wrapping_add(x: u64, y: u64): u64
public fun wrapping_sub(x: u64, y: u64): u64
public fun wrapping_mul(x: u64, y: u64): u64
public fun try_add(x: u64, y: u64): (bool, u64)
public fun try_sub(x: u64, y: u64): (bool, u64)
public fun try_mul(x: u64, y: u64): (bool, u64)
public fun try_div_down(x: u64, y: u64): (bool, u64)
public fun try_div_up(x: u64, y: u64): (bool, u64)
public fun try_mul_div_down(x: u64, y: u64, z: u64): (bool, u64)
public fun try_mul_div_up(x: u64, y: u64, z: u64): (bool, u64)
public fun try_mod(x: u64, y: u64): (bool, u64)
public fun mul(x: u64, y: u64): u64
public fun div_down(x: u64, y: u64): u64
public fun div_up(a: u64, b: u64): u64
public fun mul_div_down(x: u64, y: u64, z: u64): u64
public fun mul_div_up(x: u64, y: u64, z: u64): u64
public fun min(x: u64, y: u64): u64
public fun max(x: u64, y: u64): u64
public fun clamp(x: u64, lower: u64, upper: u64): u64
public fun diff(x: u64, y: u64): u64
public fun pow(n: u128, e: u128): u128
public fun sum(nums: vector<u64>): u64
public fun average(x: u64, y: u64): u64
public fun average_vector(nums: vector<u64>): u64
public fun sqrt_down(x: u64): u64
public fun sqrt_up(a: u64): u64
public fun log2_down(value: u64): u8
public fun log2_up(value: u64): u16
public fun log10_down(value: u64): u8
public fun log10_up(value: u64): u8 
public fun log256_down(x: u64): u8
public fun log256_up(x: u64): u8
const MAX_U128: u256 = 340282366920938463463374607431768211455;
public fun try_add(x: u128, y: u128): (bool, u128)
public fun try_sub(x: u128, y: u128): (bool, u128)
public fun try_mul(x: u128, y: u128): (bool, u128)
public fun try_div_down(x: u128, y: u128): (bool, u128)
public fun try_div_up(x: u128, y: u128): (bool, u128)
public fun try_mul_div_down(x: u128, y: u128, z: u128): (bool, u128)
public fun try_mul_div_up(x: u128, y: u128, z: u128): (bool, u128)
public fun try_mod(x: u128, y: u128): (bool, u128)
public fun mul(x: u128, y: u128): u128
public fun div_down(x: u128, y: u128): u128
public fun div_up(a: u128, b: u128): u128
public fun mul_div_down(x: u128, y: u128, z: u128): u128
public fun mul_div_up(x: u128, y: u128, z: u128): u128
public fun min(a: u128, b: u128): u128
public fun max(x: u128, y: u128): u128
public fun clamp(x: u128, lower: u128, upper: u128): u128
public fun diff(x: u128, y: u128): u128
public fun pow(n: u128, e: u128): u128
public fun sum(nums: vector<u128>): u128
public fun average(a: u128, b: u128): u128
public fun average_vector(nums: vector<u128>): u128
public fun sqrt_down(a: u128): u128
public fun sqrt_up(a: u128): u128
public fun log2_down(x: u128): u8
public fun log2_up(x: u128): u16
public fun log10_down(x: u128): u8
public fun log10_up(x: u128): u8
public fun log256_down(x: u128): u8
public fun log256_up(x: u128): u8
134KB
Su Litepaper Draft V1.pdf
pdf
here
here
Compound
here
Mirror Protocol
https://github.com/interest-protocol/bps
https://github.com/interest-protocol/constant-product
https://github.com/interest-protocol/interest-math
https://github.com/interest-protocol/ipx-coin-standard
https://github.com/interest-protocol/
https://github.com/interest-protocol/coin-x-oracle
https://github.com/interest-protocol/coin-x-oracle/blob/main/contracts/sources/pyth.move
module coin_x_oracle::pyth_oracle {
  // === Imports ===
  use std::type_name;
  
  use sui::object;
  use sui::math::pow;
  use sui::object::ID;
  use sui::clock::Clock;
  use sui::dynamic_field as df;

  use suitears::fixed_point_wad;
  use suitears::math256::mul_div_down;
  use suitears::owner::{Self, OwnerCap};
  use suitears::oracle::{Self, Oracle, Request};  

  use pyth::i64;
  use pyth::state::State as PythState;
  use pyth::price::Self as pyth_price;
  use pyth::pyth::get_price as pyth_get_price;
  use pyth::price_info::{Self, PriceInfoObject};

  // === Errors ===

  const EInvalidPriceObjectInfo: u64 = 0;
  const EZeroPrice: u64 = 1;
  const EPriceConfidenceOutOfRange: u64 = 2;

  // === Constants ===

  const POW_10_18: u256 = 1000000000000000000; // 1e18
  const TWO_PERCENT: u256 = 20000000000000000; // 0.02e18
  const HUNDRED_PERCENT: u256 = 1000000000000000000; // 1e18
  const TIME_SCALAR: u64 = 1000;

  // === Structs ===

  struct PriceInfoObjectKey has copy, drop, store {}

  struct ConfidenceKey has copy, drop, store {}

  struct PythFeed has drop {}

  // === Public-Mutative Functions ===

  /*
  * @notice Adds a `PythFeed` report to a `suitears::oracle::Request`.  
  *
  * @param self A `suiterars::oracle::Oracle` with this module's witness.    
  * @param request A hot potato issued from the `self` to create a `suiterars::oracle::Price`.  
  * @param wormhole_state The state of the Wormhole module on Sui.
  * @param pyth_state The state of the Pyth module on Sui.
  * @param price_info_object An object that contains price information. One per asset.
  * @param clock_object The shared Clock object from Sui.
  *
  * aborts-if:    
  * - The `price_info_object` is not whitelisted.   
  * - The price confidence is out of range.  
  * - The price is negative or zero.   
  */
  public fun report<Witness: drop>(
    oracle: &Oracle<Witness>, 
    request: &mut Request, 
    pyth_state: &PythState,
    price_info_object: &mut PriceInfoObject,
    clock_object: &Clock
  ) {
    let whitelisted_id = *df::borrow<PriceInfoObjectKey, ID>(oracle::uid(oracle), PriceInfoObjectKey {});

    assert!(whitelisted_id == price_info::uid_to_inner(price_info_object), EInvalidPriceObjectInfo);

    // Get the price raw value, exponent and timestamp
    let pyth_price = pyth_get_price(pyth_state, price_info_object, clock_object);
    let pyth_price_value = pyth_price::get_price(&pyth_price);
    let pyth_price_expo = pyth_price::get_expo(&pyth_price);
    let latest_timestamp = pyth_price::get_timestamp(&pyth_price);
    let price_conf = pyth_price::get_conf(&pyth_price);

    let pyth_price_u64 = i64::get_magnitude_if_positive(&pyth_price_value);

    assert_price_conf(oracle, pyth_price_u64, price_conf);

    assert!(pyth_price_u64 != 0, EZeroPrice);

    let is_exponent_negative = i64::get_is_negative(&pyth_price_expo);
    
    let pyth_exp_u64 = if (is_exponent_negative) 
      i64::get_magnitude_if_negative(&pyth_price_expo) 
    else 
      i64::get_magnitude_if_positive(&pyth_price_expo);

    let value = if (is_exponent_negative) 
      mul_div_down((pyth_price_u64 as u256), POW_10_18, (pow(10, (pyth_exp_u64 as u8)) as u256))
    else 
      (pyth_price_u64 as u256)  * (pow(10, 18 - (pyth_exp_u64 as u8)) as u256);

    oracle::report(request, PythFeed {}, latest_timestamp * TIME_SCALAR, (value as u128), 18);
  }  

  // === Admin Functions ===  

  /*
  * @notice Adds the `PythFeed` feed to the `oracle`.  
  *
  * @dev By default, this oracle will require prices to have a confidence level of 98% or higher.
  * 
  * @param self The `suiterars::oracle::Oracle` that will require a Pyth report.     
  * @param cap The `suitears::owner::OwnerCap` of `self`.   
  * @param price_info_object This Pyth Network Price Info Object will be whitelisted.
  */
  public fun add<Witness: drop>(oracle: &mut Oracle<Witness>, cap: &OwnerCap<Witness>, price_info_object: &PriceInfoObject) {
    oracle::add(oracle, cap, type_name::get<PythFeed>());
    let uid = oracle::uid_mut(oracle, cap);
    df::add(uid, PriceInfoObjectKey {}, price_info::uid_to_inner(price_info_object));
    df::add(uid, ConfidenceKey {}, TWO_PERCENT);
  }  

  /*
  * @notice Updates the required confidence interval percentage for the `self`.  
  * 
  * @dev Note that you can add a confidence interval percentage of 0%. We recommend a value higher than 95%.
  *
  * @param self The `suiterars::oracle::Oracle` that will require a Pyth report.     
  * @param cap The `suitears::owner::OwnerCap` of `self`.   
  * @param conf The new confidence.
  *
  * aborts-if 
  * - The `cap` does not own the `self`.
  * - The `conf` is higher than 100%.
  */
  public fun update_confidence<Witness: drop>(oracle: &mut Oracle<Witness>, cap: &OwnerCap<Witness>, conf: u256) {
    owner::assert_ownership(cap, object::id(oracle));
    let saved_conf = df::borrow_mut<ConfidenceKey, u256>(oracle::uid_mut(oracle, cap), ConfidenceKey {});
    *saved_conf = HUNDRED_PERCENT - conf;
  }

  // === Private Functions ===
  
  /*
  * @notice Ensures that we are reporting a price within the required confidence interval. 
  *
  * @dev Read about price confidence intervals here: https://docs.pyth.network/price-feeds/pythnet-price-feeds/best-practices
  *
  * @param self The `suiterars::oracle::Oracle` that contains the required confidence percentage.   
  * @param price_value The price
  * @param price_conf The confidence interval for the `price_value`
  *
  * aborts-if:  
  * - The `price_value`'s confidence interval is lower than the `oracle` allows. 
  */
  fun assert_price_conf<Witness: drop>(oracle: &Oracle<Witness>, price_value: u64, price_conf: u64) {
    let price_conf_percentage = fixed_point_wad::div_up((price_conf as u256), (price_value as u256));
    let required_conf = *df::borrow<ConfidenceKey, u256>(oracle::uid(oracle), ConfidenceKey {});
    assert!(required_conf >= price_conf_percentage, EPriceConfidenceOutOfRange);
  }  
}