# Moon.cx

Welcome to Moon.cx!

<figure><img src="/files/vRWSy9YsBNAWPGxb9Piv" alt=""><figcaption></figcaption></figure>

**Moon.cx** is a DeFi protocol built on the **TON blockchain**, featuring a decentralized exchange (DEX) with support for limit orders. \
The platform offers users a secure and efficient way to trade crypto assets, leveraging the high speed and low fees of the TON network. \
Moon.cx combines the functionality of modern exchanges with a decentralized approach, providing tools for effective asset management.


# DEX

At its foundation, this solution operates as a standard AMM DEX but introduces critical architectural improvements to address key inefficiencies.

Our unified vault-pool contract eliminates bottlenecks, reducing gas costs and complexity. The decentralized booster system enables permissionless pool enhancement through autonomous smart contracts, with fair reward distribution for all LPs.

Developers gain granular control over transaction flows via our flexible execution framework. The result is a capital-efficient, truly non-custodial DEX that solves core inefficiencies while maintaining full AMM functionality.


# Swap

We streamlined the transaction chain by minimizing the number of contracts involved. Keeping all pools and their linked wallets within the same shards has greatly improved processing efficiency across the chain. This optimization has led to faster transactions and lower gas costs.

<figure><img src="/files/HAISch1mPfQss5qPWH7N" alt=""><figcaption></figcaption></figure>


# Liquidity

<figure><img src="/files/jNQXD8S5D2Qk17kdRXkt" alt=""><figcaption></figcaption></figure>


# Boost

Our non-custodial booster system enables direct pool enhancement without third-party asset custody, completely eliminating trust assumptions and counterparty risk.&#x20;

The flexible implementation allows either deploying autonomous booster contracts or executing instant boost transactions through our SDK - both methods maintain full self-custody.\
\
The booster enhances the pool's liquidity reserves, automatically allocating the boosted amount proportionally to all LP token holders. As a result, the booster’s rewards are fully channeled back into the pool as reinvestment.

<figure><img src="/files/F4SedmEyU63pshDv4sRz" alt=""><figcaption></figcaption></figure>


# ORDER

**Moon.cx** enables the creation of limit orders directly on the **TON blockchain** using smart contracts. Each order operates as an independent smart contract, ensuring complete autonomy and no reliance on other orders.

* **Maker fee:** 0%
* **Taker fee:** 0.2%

The **Maker** (order creator) pays a one-time network fee to cover blockchain costs but incurs no protocol fees. This ensures that when the order is filled, the Maker receives the exact amount of tokens at the specified rate.

The **Taker** (order executor) covers both reduced network fees and the protocol fee. Additionally, the Taker who fills the remaining order volume receives a small premium in the form of the residual TON balance from the order's address.

This structure ensures transparency, efficiency, and fair incentives for all participants.

Learn more about [**Lock Orders**](/protocol/order/lock) and [**Vesting Orders**](/protocol/order/vesting)**.**

<figure><img src="/files/WddWTZIjboSQEYPtvYHm" alt=""><figcaption></figcaption></figure>


# Lock

During the order creation process, it is possible to **"lock"** the order.\
A **"locked"** order cannot be canceled and will remain on the blockchain until it is fully executed.\
While this feature may not be of immediate interest to the average user, it presents a valuable tool for token creators.

By utilizing **Lock Orders**, you can establish a **price floor** for your token.\
By placing an order at a specific price and locking it, you can build trust within your community and provide price support during market downturns.

This feature demonstrates your commitment to maintaining token value, fostering confidence among investors and stakeholders.\
\
You can combine the **Lock** functionality with [**Vesting**](/protocol/order/vesting) to create a robust and strategic approach to token management.

<figure><img src="/files/SDeWEkEIgAamSxWdAnue" alt=""><figcaption></figcaption></figure>


# Vesting

During the order creation process, you can enable **Vesting**.\
**Vesting** means that the executor of the order (Taker) will receive the tokens from the order only after a predefined period of time has elapsed. This time frame can be set at the time of order creation.

Such orders are particularly beneficial for token creators. They allow you to sell large volumes of tokens at a discount without destabilizing the market. **This approach is far more sustainable and community-friendly than abrupt sell-offs.**

It’s important to note that **Vesting Orders** can only have a single Taker, who must fill the entire order volume. If the Taker sends an amount smaller than the order volume, the funds will be automatically returned.

Once the Taker fills the order, the countdown to token release (vesting time) begins. After the vesting period expires, the Taker receives the tokens along with a small residual balance of TON from the order address.\
The order creator (Maker) receives their tokens immediately upon order execution, without waiting for the vesting period to conclude.

This mechanism ensures a balanced and secure approach to token distribution, fostering trust and stability within the ecosystem.

<figure><img src="/files/r93r3lgSYjGCdCRCxUNz" alt=""><figcaption></figcaption></figure>


# SDK

**To streamline development, we’ve prepared an SDK (Software Development Kit) for seamless interaction with our protocol.**

**To install the SDK, run the following command:**

```
npm install @ton/core @ton/ton @ton/crypto @ton-community/assets-sdk @mooncx/sdk
```

For detailed guides and examples:\
[DEX](/developers/sdk/dex)\
[ORDER](/developers/sdk/order)\
\
Something wrong?\
<https://t.me/mooncx_help>


# DEX

## Prepare

```typescript
if(!process.env.MNEMONIC) {
    throw new Error('MNEMINIC IS REQUIRED!');
}

// init wallet
const mnemonic = process.env.MNEMONIC.split(" ");
const keys = await mnemonicToPrivateKey(mnemonic);

const wallet = tonClient.open(
    WalletContractV4.create({
        workchain: 0,
        publicKey: keys.publicKey
    })
);

// get config
const apiConfig = await getApiConfig();

// get listed assets
const apiAssets = await getApiAssets();

// get pools
const apiPools = await getApiPools();

// init pool
const dexPool = tonClient.open(DexPool.createFromAddress(apiPools[0]!.address));
```

## TON swap

```typescript
// simple swap 1 TON to USDT
await dexPool.sendSwapTon(wallet.sender(keys.secretKey), 123, toNano('1'));

// complex swap
await dexPool.sendSwapTon(wallet.sender(keys.secretKey), 321, toNano('2'), {
    gas: toNano('0.25'), // custom gas
    min_out: 1000n, // custom min_out
    deadline: 1743889864, // unix time
    excess: someAddr, // all excesses from this hop will be sent to this address
    referral: refAddr, // referral cut will be sent to this address
    next_fulfill: someCell, // if swap succeed, this payload will be sent to specified address
    next_reject: someCell // if swap failed, this payload will be sent to specified address
});

// multi hop. TON -> USDT -> BOLT
const nextFulfillCell = beginCell()
    .storeAddress(nextPool) // USDT-BOLT pool
    .storeMaybeRef(packSwapPayloadJetton({ // payload which will be sent, in this case swap payload
        min_out: 1000n,
        excess: wallet.address, // always set excess!
        next_fulfill: beginCell()
            .storeAddress(wallet.address) // recipient after last hop
            .storeMaybeRef(null) // empty recipient payload
            .endCell(),
        next_reject: beginCell()
            .storeAddress(wallet.address) // recipient if something went wrong on last hop
            .storeMaybeRef(null)
            .endCell()
    }))
    .endCell()

await dexPool.sendSwapTon(wallet.sender(keys.secretKey), 123, toNano('10'), {
    gas: toNano('0.3'), // each hop should have 0.15 ton
    excess: wallet.address,
    next_fulfill: nextFulfillCell
    next_reject: nextRejectCell // specify reject cell in case something goes wrong
});

// you can create as many hops ask you like
const nextFulfillCell = beginCell()
    .storeAddress(nextPool)
    .storeMaybeRef(packSwapPayloadJetton({
        min_out: 1000n,
        excess: wallet.address, // always specify excess on hops! otherwise will be sent to previous pool
        nextFulfill: beginCell()
            .storeAddress(nextPool2)
            .storeMaybeRef(packSwapPayloadJetton({
                min_out: 2000n,
                nextFulfill: beginCell()
                    .storeAddress(nextPool3)
                    .storeMaybeRef(packSwapPayloadTon(123, toNano('0.5'), {
                        nextFulfill: beginCell()
                            .storeAddress(nextPool4)
                            .storeMaybeRef(......)
                        .endCell()
                    }))
                    .endCell()
            }))
            .endCell()
    }))

await dexPool.sendSwapTon(wallet.sender(keys.secretKey), 123, toNano('13'), {
    gas: toNano('0.15') * hops_count, // each hop = 0.15 ton - excess
    excess: wallet.address,
    next_fulfill: nextFulfillCell
});
```

## JETTON swap

```typescript
// Same logic, but we have to init jetton wallet for specified jetton

// init master
const jettonMaster = tonClient.open(JettonMinter.createFromAddress(asset2_id));

// init wallet
const jettonWallet = await jettonMaster.getWallet(wallet.address);

// simple swap 1 USDT to TON
await dexPool.sendSwapJetton(wallet.sender(keys.secretKey), jettonWallet, 123, 1000000n);

// complex jetton swap
await dexPool.sendSwapJetton(wallet.sender(keys.secretKey), jettonWallet, 321, 1000000n, {
    forward_amount: toNano('0.3'), // each hop should have 0.15 ton
    min_out: 100n,
    deadline: 1743889864,
    excess: wallet.address,
    referral: null,
    next_fulfill: someCell,
    next_reject: otherCell
});

// same thing for hops
await dexPool.sendSwapJetton(wallet.sender(keys.secretKey), jettonWallet, 321, 1000000n, {
    forward_amount: toNano('0.3'), // each hop should have 0.15 ton
    min_out: 100n,
    deadline: 1743889864,
    excess: wallet.address,
    referral: null,
    next_fulfill: beginCell()
        .storeAddress(nextAddress)
        .storeMaybeRef(
            packSwapPayloadJetton({
                min_out: 1000n,
                excess: wallet.address // always set excess!
            })
        )
        .endCell()
});

// or any custom payload
await dexPool.sendSwapJetton(wallet.sender(keys.secretKey), jettonWallet, 321, 1000000n, {
    forward_amount: toNano('0.3'), // each hop should have 0.15 ton
    min_out: 100n,
    deadline: 1743965438,
    excess: wallet.address,
    next_fulfill: beginCell()
        .storeAddress(someAddress)
        .storeMaybeRef(
            beginCell()
                .storeUint(333, 32)
                .storeUint(777, 32)
                .storeAddress(durovAddress)
            .endCell()
        )
        .endCell()
});

```

## TON deposit liquidity

```typescript
await dexPool.sendDepositLiquidityTon(
    wallet.sender(keys.secretKey),
    123, // query_id
    toNano('2'), // amount
    1000n // min_lp_out
);
```

## JETTON deposit liquidity

```typescript
await dexPool.sendDepositLiquidityJetton(
    wallet.sender(keys.secretKey),
    jettonWallet,
    123, // query_id
    1000000n, // amount
    100n, // min_lp_out
);
```

## Withdraw liquidity (burn LP)

```typescript
await dexPool.sendBurnLp(
    wallet.sender(keys.secretKey),
    lpJettonWallet,
    123, // query_id
    1230000n, // amount
);
```

## Create booster for pool

```typescript
const boosterFactory = tonClient.open(DexBoosterFactory.createFromAddress(apiConfig.booster_factory));

// iteration_amount = boost_amount / iterations

await boosterFactory.sendCreateBoosterTon(
    wallet.sender(keys.secretKey),
    123, // query_id
    dexPool.address, // pool
    toNano('5'), // total boost_amount
    2, // iterations
    3600, // period
);

await boosterFactory.sendCreateBoosterJetton(
    wallet.sender(keys.secretKey),
    jettonWallet,
    123, // query_id,
    dexPool.address, // pool
    toNano('10'), // total boost_amount
    5, // iterations
    5000, // period (seconds between iterations)
);
```

## Getters

```typescript
dexPool.getPool(); // all data in one call
dexPool.getEstimatedLp(asset1_id, asset1_amount, asset2_id, asset2_amount);
dexPool.getEstimatedLpBurn(lp_amount);
dexPool.getEstimatedSwapOut(asset_id, asset_amount);
dexPool.getFees();
dexPool.getAssets();
dexPool.getWallets();
dexPool.getReserves();
dexPool.getLpTotal();
dexPool.getLpAccount(owner);
dexPool.getWalletAddress(owner);
```


# ORDER

## Prepare

```typescript
if(!process.env.MNEMONIC) {
    throw new Error('MNEMINIC IS REQUIRED!');
}

// init wallet
const mnemonic = process.env.MNEMONIC.split(" ");
const keys = await mnemonicToPrivateKey(mnemonic);

const wallet = tonClient.open(
    WalletContractV4.create({
        workchain: 0,
        publicKey: keys.publicKey
    })
);

// get config
const apiConfig = await getApiConfig();

// get listed assets
const apiAssets = await getApiAssets();

// init order factory
const orderFactory = tonClient.open(OrderFactory.createFromAddress(apiConfig.order_factory));
```

## Create order

```typescript
// select assets
const asset1_id = Address.parse(apiAssets[2].asset_id); // bolt
const asset2_id = Address.parse(apiAssets[1].asset_id); // usdt, in this case

// create order TON -> JETTON
await orderFactory.sendCreateOrderTon(
    wallet.sender(keys.secretKey),
    123, // query_id
    toNano('10'), // amount
    asset2_id, // trade ton for
    calculateRate(toNano('10'), toNano('20')), // rate 1 : 2
    false, // lock order?
    3000, // 3000 seconds vesting time
);

// create order JETTON -> TON/JETTON
await orderFactory.sendCreateOrderJetton(
    wallet.sender(keys.secretKey),
    123,
    toNano('20'),
    asset1_id, // BOLT
    asset2_id, // USDT in this case. Put null if you want BOLT -> TON
    calculateRate(toNano('20'), 5000000n),
    true, // order locked, can't be cancelled
    0 // no vesting
);

// Use calculateRate. 1st amount - you send, 2nd - you wish to receive.
```

## Fill order

```typescript
// fill order with ton
await order.sendOrderFillTon(
    wallet.sender(keys.secretKey),
    123, // query_id
    toNano('10'), // amount
    someAddress, // recipient address, will receive fill result
    someCell, // recipient payload
    someOtherAddress, // reject address, will receive refund on any fails
);

// fill order with jetton
const jettonMaster = tonClient.open(JettonMinter.createFromAddress(asset2_id));
const jettonWallet = await jettonMaster.getWallet(wallet.address);

await order.sendOrderFillJetton(
    wallet.sender(keys.secretKey),
    jettonWallet, // your jetton wallet 
    123, // query_id
    13000000n, // amount
    wallet.address, // recipient address
    null, // recipient payload
    wallet.address // reject address
);
```

## Cancel order

```typescript
// init order
const order = tonClient.open(Order.createFromAddress(orderAddr));

// cancel order
await order.sendCancel(
    wallet.sender(keys.secretKey),
    123, // query_id
);
```

## Vesting trigger

```typescript
// You can manually send vesting trigger

await order.sendExternalVestingTrigger();
```

## Getters

```typescript
const orderData = await order.getOrder(); // full data in one call
const fillOut = await order.getFillOut(100000n); // fill result
const vestingData = await order.getVestingData(); // will fail if order status != 7.
const orderStatus = await order.getStatus();
const orderAmount = await order.getAmount();
const orderAssets = await order.getAssets();
const orderWallets = await order.getWallets();
```


# Listing

**Requirements for Listing Your Asset on Moon:**

1. **Open-Source Code:** The token’s smart contract must be publicly verifiable.
2. **Minimum Liquidity:** A minimum initial liquidity of $5,000 is required.
3. **Active Community:** The project must demonstrate an engaged and growing community.

**Application submissions should be sent to:** <https://t.me/mooncx_help>


