https://github.com/broxus/jetton
https://github.com/broxus/jetton
Last synced: 10 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/broxus/jetton
- Owner: broxus
- License: mit
- Created: 2024-09-10T13:28:52.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-01-21T13:36:54.000Z (over 1 year ago)
- Last Synced: 2025-01-29T02:46:47.731Z (over 1 year ago)
- Language: TypeScript
- Size: 754 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# bridge jetton-contracts
## Build and test
```shell
npm install
npm run build
npm run test
```
Note: if you experience issues with running the test try to test using node.js 14
## Info
Current jetton contracts extend and modify some behavior of original contracts https://github.com/ton-blockchain/minter-contract.
But it is fully compatible with contracts that use ordinary jettons.
## Features
- jetton-platform.fc contract which allows the upgrade of wallet contracts
- on-chain jetton content encoding
- on_accept_tokens_burn callback for integration with other contracts
- upgrade_wallet and upgrade_minter opcodes for minter and wallet contracts upgrade
- additional admin opcodes in root set_wallet_code and deploy_wallet
- provide_info and take_info to get the minter's decimals, name, and symbol for another contract
## Features description
### jetton-platform.fc
The platform allows for upgradable and secure contracts without breaking compatibility between wallets of different versions.
Each contract in TVM receives a deterministic address from its code and init data: address = hash(code + init_data).
To make upgradable jetton wallets we use jetton-platform.fc as code and address of its owner and minter as init data.
To check that the sender is a valid Jetton wallet we also use platform code with the owner's and minter's addresses to derive a valid address
```func
cell calculate_jetton_wallet_state_init(
slice owner_address,
slice jetton_master_address,
cell jetton_platform_code
) inline {
cell data = pack_jetton_wallet_data(
0,
owner_address,
jetton_master_address,
begin_cell().end_cell(),
jetton_platform_code,
0
);
return begin_cell()
.store_uint(0, 2)
.store_dict(jetton_platform_code) ;; code
.store_dict(data) ;; init data
.store_uint(0, 1)
.end_cell();
}
```
To upgrade wallet from platform and perform receive_tokens:
```func
;; update contract's code for future txs
set_code(wallet_code);
;; update contract's code for current receive_tokens() call. God bless us!!!
set_c3(wallet_code.begin_parse().bless());
;; for newly deployed jetton wallet only receive_tokens() call is possible
receive_tokens(
ms,
sender_address,
my_balance,
fwd_fee,
msg_value
);
```
### On-chain metadata
Jetton's metadata builds on-chain.
Note: replace Jetton's icon URL with yours
```func
slice image_slice = begin_cell()
.store_slice("https://ton-tokens-api.bf.works/image/")
.store_slice(my_workchain)
.store_slice(":")
.store_slice(my_hash)
.store_slice(".svg")
.end_cell()
.begin_parse();
cell content_dict = new_dict();
content_dict~udict_set_ref(256, "image"H, pack_metadata_value(image_slice));
content_dict~udict_set_ref(256, "decimals"H, pack_metadata_value(decimals_slice));
content_dict~udict_set_ref(256, "name"H, pack_metadata_value(name.begin_parse()));
content_dict~udict_set_ref(256, "symbol"H, pack_metadata_value(symbol_slice));
cell onchain_content = begin_cell()
.store_uint(0, 8)
.store_dict(content_dict)
.end_cell();
```
### op::on_accept_tokens_burn()
When the wallet's owner burns his jettons he will receive a notification callback from the minter.
It needs for integration with other contracts or protocols e.a.: DEXes, lendings, bridges, etc.
### op::upgrade_wallet() and op::upgrade_minter()
It's also possible to upgrade wallet and minter contracts anytime if you find vulnerabilities in contracts
or decided to extend their interface
### op::provide_info() and op::take_info()
These opcodes will provide you info about Jetton from the minter contract: decimals, name, symbol, etc.
It's useful if you need to identify your contracts by tokens' names or need to make price oracle,
curve-like DEX pools or some other useful stuff that needs Jetton's decimals, symbol, name, or your
custom metadata (chain ID and base token address for a bridge for example)
### Changed gas management in wallet's op::internal_transfer()
When the wallet receives a transfer it will try to keep its balance before the tx
or at least take some message's gas to pay for its storage.
Wallet's balance can be: [min_tons_for_storage, ∞)
```func
raw_reserve(max(ton_balance_before_msg, min_tons_for_storage), 2);
```
Also, you don't need to split your gas for op::transfer_notification() and op::excesses().
In most cases, contracts want to send whole gas to notification or excesses callback.
Use a non-zero forward amount to send the whole gas to op::transfer_notification().
Otherwise, the whole gas will be sent to op::excesses()
## Other minor features
- op::drain() in minter and wallet contracts to drain excesses from the contract's balance
- jetton-wallet.fc#get_wallet_platform_data() getter to receive platform code and current wallet's version
- jetton-minter.fc#get_jetton_meta() getter to receive raw metadata without dictionary
- jetton-minter.fc#get_jetton_platform_data() getter to receive platform code and current wallet's code version