Skip to content

Commit 02d2ae6

Browse files
authored
Merge branch 'main' into runvm-security
2 parents 73a82df + 49482cc commit 02d2ae6

File tree

6 files changed

+110
-12
lines changed

6 files changed

+110
-12
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88

99
</div>
1010

11+
Check out T-Dex wip dApp frontend to perform swaps with web UI:
12+
13+
Link: https://tact-lang.github.io/dex-frontend/
14+
Repo: https://github.com/tact-lang/dex-frontend
15+
16+
You can use this example to see how to integrate with T-Dex contracts from the frontend or execute swap transactions.
17+
1118
## Project Goals
1219

1320
- Creating a state-of-the-art fully open-source decentralized exchange (DEX)
@@ -30,6 +37,32 @@ Check these docs to learn about how T-Dex works, its semantics and how to integr
3037
- How to work with Factory, TODO
3138
- How to create new pool and vaults, TODO
3239

40+
## Examples and usage
41+
42+
### Contracts
43+
44+
T-Dex contracts are deployed in testnet and are ready for usage and testing purposes.
45+
46+
- [Jetton A](https://testnet.tonviewer.com/kQBCzXhQNxS727KxwsHld8aVNoFpSka0Xzr3GUBOxC_l2gQM)
47+
- [Jetton A Vault](https://testnet.tonviewer.com/kQBBWii_pqdQWcWQ9pWPC7lt1qoNngdZ9TuUMgT81TFgQiM_)
48+
49+
- [Jetton B](https://testnet.tonviewer.com/kQDO8Rt30nYL8RbXOWWMCqY3E4o-mN-tum0MTlABiFTDtz2p)
50+
- [Jetton B Vault](https://testnet.tonviewer.com/kQBtrwWIuAD_KJIoI14S3jxcANwnL4TrTvsj88cGXVCfG6y2)
51+
52+
- [A-B Jettons pool](https://testnet.tonviewer.com/kQDRJqnVNdRdCH8u9cVclk-iZKpI4bVMBvgyTWfNyI6rTtQH)
53+
- [Proxy liquidity deposit](https://testnet.tonviewer.com/0QBa3_cmTS4lg_pGBt_k5t1NEfHFnsDm8Y2UkD_t3MCQHAG7) (Non-existent because was destroyed after tx)
54+
55+
- [T-Dex factory](https://testnet.tonviewer.com/kQDR9j1SuiGtbSi7NZNgNwlDPIWZFEN5BLMz6AOd-IpGunLG) (No tx on it, used for get-methods)
56+
- [Ton Vault](https://testnet.tonviewer.com/kQDTsG5OoAbrtTRpYMHlmqDXwI9mj3Iv-wj-NNrNf0BDG1dJ) (Inited, but no pools with it yet)
57+
58+
### Transactions
59+
60+
- [A-B Jettons liquidity provisioning](https://testnet.tonviewer.com/transaction/21825ccd231a2aae8dbb95307f9a3b46cff61f2f863a4b9a1a35ec6c6e18f4f3) (Lp jettons minting in the end)
61+
- [A->B Jettons exact-out swap with slippage](https://testnet.tonviewer.com/transaction/91c4004bda0941ee16a611689bacdd4105b6ef230d3b6b9419ec20d40b784cfa) (Notice partial A jetton refund because of slippage)
62+
- [A->B Jettons exact-in swap](https://testnet.tonviewer.com/transaction/8645178e74ab066e86d5bf1912bf05298c1ecf68887a8d38463a8a9aa2c57fda)
63+
- [B->A Jettons swap with low decimals](https://testnet.tonviewer.com/transaction/fdabd6abb38adf2a705417a809f86b8421638479439466a99bb977ebca496cd9)
64+
- [B Vault initialization](https://testnet.tonviewer.com/transaction/c6f4a9758ab80fd2172af8f82e40d55a98cec4e79df32734761a03a90450cb81)
65+
3366
## DEX Architecture
3467

3568
DEX is built on a modular architecture with clear component separation:

sources/contracts/vaults/ton-vault.tact

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ message(0x7362d09c) UnexpectedJettonNotification {
2727
forwardPayload: Slice as remaining;
2828
}
2929

30-
contract TonVault(
31-
admin: Address,
32-
) with VaultInterface {
30+
contract TonVault() with VaultInterface {
3331
override fun handlePayout(msg: PayoutFromPool) {
3432
let sortedAddresses = sortAddresses(myAddress(), msg.otherVault);
3533
let poolInit = initOf AmmPool(sortedAddresses.lower, sortedAddresses.higher, 0, 0, 0, null);
@@ -41,7 +39,9 @@ contract TonVault(
4139
value: msg.amount,
4240
mode: SendRemainingValue,
4341
bounce: false,
44-
body: msg.payloadToForward,
42+
body: PayoutFromTonVault {
43+
body: msg.payloadToForward,
44+
}.toCell(),
4545
});
4646
}
4747

sources/contracts/vaults/vault-interface.tact

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ extends inline fun numberOfHops(self: SwapParameters): Int {
5151
}
5252
}
5353

54+
message(0x2d8b123a) PayoutFromTonVault {
55+
body: Cell?;
56+
}
57+
5458
struct LiquidityDepositInitData {
5559
otherVault: Address;
5660
otherAmount: Int as coins;

sources/scripts/deploy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const main = async () => {
7272
// )
7373
console.log("Minted Token A", jettonMinterA.address.toString())
7474

75-
const tonVaultContract = await TonVault.fromInit(randomAddress())
75+
const tonVaultContract = await TonVault.fromInit()
7676
const _tonVault = client.open(tonVaultContract)
7777
// const deployResult = await tonVault.send(
7878
// deployerWallet.sender(keyPair.secretKey),

sources/tests/ton-vault.spec.ts

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
// SPDX-License-Identifier: MIT
22
// Copyright © 2025 TON Studio
33

4-
import {Blockchain} from "@ton/sandbox"
4+
import {Blockchain, internal} from "@ton/sandbox"
55
import {createJetton, createTonVault} from "../utils/environment"
6-
import {beginCell} from "@ton/core"
7-
import {findTransactionRequired, flattenTransaction} from "@ton/test-utils"
6+
import {beginCell, toNano} from "@ton/core"
7+
import {findTransactionRequired, flattenTransaction, randomAddress} from "@ton/test-utils"
88
import {randomInt} from "node:crypto"
9-
import {TonVault} from "../output/DEX_TonVault"
9+
import {loadPayoutFromTonVault, storePayoutFromPool, TonVault} from "../output/DEX_TonVault"
10+
import {AmmPool} from "../output/DEX_AmmPool"
11+
import {sortAddresses} from "../utils/deployUtils"
1012

1113
describe("TON Vault", () => {
1214
test("Jettons are returned if sent to TON Vault", async () => {
@@ -46,4 +48,65 @@ describe("TON Vault", () => {
4648
const finalJettonBalance = await jetton.wallet.getJettonBalance()
4749
expect(finalJettonBalance).toEqual(initialBalance)
4850
})
51+
test("TON Vault successfully transfers swap payload", async () => {
52+
const blockchain = await Blockchain.create()
53+
54+
const tonVaultContract = await TonVault.fromInit()
55+
const openedTonVault = blockchain.openContract(tonVaultContract)
56+
const deployer = await blockchain.treasury("deployer")
57+
// Deploy contract
58+
const deployRes = await openedTonVault.send(
59+
deployer.getSender(),
60+
{value: toNano(0.1)},
61+
null,
62+
)
63+
expect(deployRes.transactions).toHaveTransaction({
64+
on: tonVaultContract.address,
65+
deploy: true,
66+
})
67+
68+
const otherVaultAddress = randomAddress(0)
69+
const sortedAddresses = sortAddresses(tonVaultContract.address, otherVaultAddress, 0n, 0n)
70+
const randomAmmPool = await AmmPool.fromInit(
71+
sortedAddresses.lower,
72+
sortedAddresses.higher,
73+
0n,
74+
0n,
75+
0n,
76+
null,
77+
)
78+
const tonVaultObject = await blockchain.getContract(tonVaultContract.address)
79+
80+
const randomReceiver = randomAddress(0)
81+
const payloadToForward = beginCell()
82+
.storeStringTail("Random quite big payload. User can encode anything here")
83+
.endCell()
84+
const res = await tonVaultObject.receiveMessage(
85+
internal({
86+
from: randomAmmPool.address,
87+
to: tonVaultContract.address,
88+
value: toNano(0.1),
89+
body: beginCell()
90+
.store(
91+
storePayoutFromPool({
92+
$$type: "PayoutFromPool",
93+
amount: 0n,
94+
otherVault: otherVaultAddress,
95+
receiver: randomReceiver,
96+
payloadToForward: payloadToForward,
97+
}),
98+
)
99+
.endCell(),
100+
}),
101+
)
102+
const flatTx = flattenTransaction(res)
103+
expect(flatTx.exitCode).toEqual(0)
104+
expect(flatTx.actionResultCode).toEqual(0)
105+
expect(res.outMessagesCount).toEqual(1)
106+
const payoutBody = res.outMessages.get(0)?.body
107+
expect(payoutBody).toBeDefined()
108+
const parsedPayout = loadPayoutFromTonVault(payoutBody!.beginParse())
109+
expect(parsedPayout.$$type).toEqual("PayoutFromTonVault")
110+
expect(parsedPayout.body).toEqualCell(payloadToForward)
111+
})
49112
})

sources/utils/environment.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,7 @@ export const createJettonVault: Create<VaultInterface<JettonTreasury>> = async (
267267
export const createTonVault: Create<VaultInterface<TonTreasury>> = async (
268268
blockchain: Blockchain,
269269
) => {
270-
const vaultOwner = await blockchain.treasury("vault-owner")
271-
272-
const vault = blockchain.openContract(await TonVault.fromInit(vaultOwner.address))
270+
const vault = blockchain.openContract(await TonVault.fromInit())
273271

274272
const wallet = await blockchain.treasury("wallet-owner")
275273

0 commit comments

Comments
 (0)