import "@stdlib/ownable"; import "./wallet"; import "./linker"; import "./constants"; @interface("org.ton.jetton.master") trait TONBTrait with Ownable { // // Storage // totalSupply: Int; mintable: Bool; owner: Address; content: Cell?; first_linker: Address?; last_linker: Address?; n_linkers: Int = 0; // // Receivers // receive(msg: TokenUpdateContent) { // Allow changing content only by owner self.requireOwner(); // Update content self.content = msg.content; } receive(msg: TokenBurnNotification) { // Check wallet self.requireWallet(msg.owner); // Update supply self.totalSupply = self.totalSupply - msg.amount; /* todo: if not enough tokens, withdraw what we have, send some tokens to the owner, add a withdrawal request */ // Withdraw send(SendParameters{ to: msg.owner, value: msg.amount, bounce: false }); } // // Get Methods // get fun get_wallet_address(owner: Address): Address { let winit: StateInit = self.getJettonWalletInit(owner); return contractAddress(winit); } get fun get_jetton_data(): JettonData { let code: Cell = self.getJettonWalletInit(myAddress()).code; return JettonData{ totalSupply: self.totalSupply, mintable: self.mintable, owner: self.owner, content: self.content, walletCode: code }; } // // Private Methods // fun mint(to: Address, amount: Int, responseAddress: Address?) { // Update total supply self.totalSupply = self.totalSupply + amount; // Create message let winit: StateInit = self.getJettonWalletInit(to); let walletAddress: Address = contractAddress(winit); let linker_init: StateInit = initOf Linker(self.n_linkers, walletAddress, myAddress()); let linker_address: Address = contractAddress(linker_init); send(SendParameters{ to: linker_address, value: linker_credit, bounce: false, body: SetLinkerNeighbor{ neighbor: self.last_linker }.toCell(), code: linker_init.code, data: linker_init.data }); self.last_linker = linker_address; self.n_linkers = self.n_linkers + 1; let wallet_msg_body: Cell = TokenTransferInternal{ amount: amount, queryId: 0, from: myAddress(), responseAddress: responseAddress, forwardTonAmount: 0, forwardPayload: emptySlice(), setLinker: self.n_linkers - 1, setLinkerAddress: linker_address }.toCell(); send(SendParameters{ to: walletAddress, value: wallet_credit, bounce: false, body: wallet_msg_body, code: winit.code, data: winit.data }); } fun burn(from: Address, amount: Int, responseAddress: Address?) { // Create message let winit: StateInit = self.getJettonWalletInit(from); let walletAddress: Address = contractAddress(winit); send(SendParameters{ to: walletAddress, value: 0, bounce: false, mode: SendRemainingValue, body: TokenBurn{ amount: amount, queryId: 0, responseAddress: responseAddress, owner: from }.toCell(), code: winit.code, data: winit.data }); } fun requireWallet(owner: Address) { let ctx: Context = context(); let winit: StateInit = self.getJettonWalletInit(owner); require(contractAddress(winit) == ctx.sender, "Invalid sender"); } virtual fun getJettonWalletInit(address: Address): StateInit { return initOf TONBWallet(myAddress(), address); } }