Skip to content

Commit

Permalink
feat: enhance max_supply logic for Jetton supply management (#24)
Browse files Browse the repository at this point in the history
### PR Summary: Update `max_supply` Attribute in Jetton Implementation

This PR updates the handling of the `max_supply` attribute to improve
flexibility and enforce stricter rules.

#### Key Changes:
1. **Optional `max_supply`**:
   - `max_supply` can be `0` to indicate unlimited supply.

2. **Minting Rules**:
   - Minting stops when `max_supply` is reached (if not `0`).
   - Unlimited minting allowed if `max_supply` is `0`.

3. **Update Restrictions**:
- `max_supply` can only be set to `0` during initialization
(`JettonInit`).
   - `max_supply` can only be increased via `JettonSetParameter`.

4. **Tests**:
- Added basic tests to verify minting behavior and `max_supply`
constraints.

---------

Co-authored-by: Suprun <[email protected]>
  • Loading branch information
iamIcarus and ya7on authored Dec 31, 2024
1 parent e4d3efc commit 2a9dff0
Show file tree
Hide file tree
Showing 4 changed files with 359 additions and 7 deletions.
18 changes: 14 additions & 4 deletions contracts/jetton/master.tact
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import "../errors.tact";
@interface("org.ton.jetton.master")
contract JettonMaster with TEP74JettonMaster, TEP89JettonDiscoverable, Deployable, OwnableTransferable {
// Maximum tokens can be minted
max_supply: Int = ton("21000000");
max_supply: Int = 0;
// Current tokens minted
current_supply: Int = 0;
// Administrator of token. Who can mint new tokens
Expand All @@ -22,6 +22,7 @@ contract JettonMaster with TEP74JettonMaster, TEP89JettonDiscoverable, Deployabl
metadata: OnchainMetadata;
// Is token initialized (to avoid double init)
deployed: Bool = false;

init(owner: Address){
self.owner = owner;
let init = initOf JettonWallet(myAddress(), myAddress());
Expand All @@ -42,7 +43,7 @@ contract JettonMaster with TEP74JettonMaster, TEP89JettonDiscoverable, Deployabl
self.metadata.set("name", msg.jetton_name);
self.metadata.set("description", msg.jetton_description);
self.metadata.set("symbol", msg.jetton_symbol);
self.max_supply = msg.max_supply;
self.max_supply = msg.max_supply > 0 ? msg.max_supply : 0;
self.notify(JettonInitOk{query_id: msg.query_id}.toCell());
self.deployed = true;
}
Expand All @@ -52,7 +53,11 @@ contract JettonMaster with TEP74JettonMaster, TEP89JettonDiscoverable, Deployabl

// Update max supply
if (msg.key == "max_supply") {
self.max_supply = msg.value.loadCoins();
//Cannot set max supply to 0 through this method
let new_max_supply = msg.value.loadCoins();
nativeThrowIf(ERROR_CODE_INVALID_AMOUNT, new_max_supply <= self.max_supply);

self.max_supply = new_max_supply;
return;
}

Expand All @@ -63,7 +68,12 @@ contract JettonMaster with TEP74JettonMaster, TEP89JettonDiscoverable, Deployabl
nativeThrowUnless(ERROR_CODE_INVALID_AMOUNT, msg.amount > 0); // Reject mint with amount <= 0
self.requireOwner();

nativeThrowIf(ERROR_MAX_SUPPLY_EXCEEDED, (self.current_supply + msg.amount) > self.max_supply);
// Ensure the new supply does not exceed the max supply
// Only for the case that max_supply is not set to unlimited (0)
if(self.max_supply > 0){
nativeThrowIf(ERROR_MAX_SUPPLY_EXCEEDED, (self.current_supply + msg.amount) > self.max_supply);
}

let init = self.discover_wallet_state_init(myAddress(), msg.destination);
let to = contractAddress(init);
send(SendParameters{
Expand Down
5 changes: 3 additions & 2 deletions tests/JettonMaster.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,14 +299,15 @@ describe('JettonMaster', () => {
expect(maxSupplyUpdateResult.transactions).toHaveTransaction({
from: deployer.address,
to: jettonMaster.address,
success: true,
success: false,
deploy: false,
op: OP_CODES.JettonSetParameter,
exitCode: 6905
});

// Checks
let jettonMasterMetadata = await jettonMaster.getGetJettonData();
expect(jettonMasterMetadata.mintable).toEqual(false);
expect(jettonMasterMetadata.mintable).toEqual(true);

let jettonContent = jettonMasterMetadata.jetton_content.beginParse();
expect(jettonContent.loadUint(8)).toEqual(0);
Expand Down
Loading

0 comments on commit 2a9dff0

Please sign in to comment.