template for a bep20 token smart contract with buy & sell function, developer fee, charity fee, and auto liquidity function in rust

Here's an example implementation of a BEP20 token smart contract with buy & sell functions, developer fee, charity fee, and auto liquidity function in Rust using the ink! framework:

main.rs
use ink_lang::contract;

contract! {
    #![env = ink_env::Environment]
    
    // Define the BEP20 token contract
    struct MyBEP20 {
        // The total supply of the token
        total_supply: balance::Balance,
        // The balance of each account
        balances: ink_storage::collections::HashMap<AccountId, balance::Balance>,
        // The allowance for each account to transfer a certain amount of tokens
        allowances: ink_storage::collections::HashMap<(AccountId, AccountId), balance::Balance>,
        // The developer fee percentage
        developer_fee_percent: u32,
        // The charity fee percentage
        charity_fee_percent: u32,
        // The auto liquidity fee percentage
        auto_liquidity_fee_percent: u32,
        // The liquidity pool balance
        liquidity_pool_balance: balance::Balance,
        // The address of the charity beneficiary
        charity_beneficiary: AccountId,
        // The address of the developer
        developer: AccountId,
    }

    impl MyBEP20 {
        // The constructor function to initialize the token contract
        #[ink(constructor)]
        pub fn new(initial_supply: balance::Balance, developer_fee_percent: u32, charity_fee_percent: u32, auto_liquidity_fee_percent: u32, charity_beneficiary: AccountId, developer: AccountId) -> Self {
            let mut balances = ink_storage::collections::HashMap::new();
            balances.insert(Self::env().caller(), initial_supply);

            Self {
                total_supply: initial_supply,
                balances,
                allowances: ink_storage::collections::HashMap::new(),
                developer_fee_percent,
                charity_fee_percent,
                auto_liquidity_fee_percent,
                liquidity_pool_balance: 0,
                charity_beneficiary,
                developer,
            }
        }

        // The buy function to purchase tokens
        #[ink(message, payable)]
        pub fn buy(&mut self) -> bool {
            // Calculate the amount of tokens to be purchased
            let tokens_to_purchase = self.calculate_tokens_to_purchase();

            // Validate the purchase amount
            let purchase_amount = self.calculate_purchase_amount(tokens_to_purchase);
            if Self::env().transferred_balance() != purchase_amount {
                return false;
            }

            // Transfer the purchase amount to the token contract
            self.env().extension().transfer_from(
                Self::env().caller(),
                Self::env().account_id(),
                purchase_amount,
            ).unwrap();

            // Update the balances
            self.balances.insert(Self::env().caller(), self.balance_of(Self::env().caller()) + tokens_to_purchase);
            self.balances.insert(Self::env().account_id(), self.balance_of(Self::env().account_id()) - tokens_to_purchase);

            // Distribute the fees
            self.distribute_fees(tokens_to_purchase);

            // Emit the event
            self.env().emit_event(Buy {
                buyer: Self::env().caller(),
                tokens: tokens_to_purchase,
                price: purchase_amount,
            });

            true
        }

        // The sell function to sell tokens
        #[ink(message)]
        pub fn sell(&mut self, tokens: balance::Balance) -> bool {
            // Validate the sell amount
            if tokens > self.balance_of(Self::env().caller()) {
                return false;
            }

            // Calculate the sell amount
            let sell_amount = self.calculate_sell_amount(tokens);

            // Transfer the sell amount to the caller
            self.env().extension().transfer(
                Self::env().caller(),
                sell_amount,
            ).unwrap();

            // Update the balances
            self.balances.insert(Self::env().caller(), self.balance_of(Self::env().caller()) - tokens);
            self.balances.insert(Self::env().account_id(), self.balance_of(Self::env().account_id()) + tokens);

            // Emit the event
            self.env().emit_event(Sell {
                seller: Self::env().caller(),
                tokens,
                price: sell_amount,
            });

            true
        }

        // The transfer function to transfer tokens
        #[ink(message)]
        pub fn transfer(&mut self, to: AccountId, tokens: balance::Balance) -> bool {
            // Validate the transfer amount
            if tokens > self.balance_of(Self::env().caller()) {
                return false;
            }

            // Update the balances
            self.balances.insert(Self::env().caller(), self.balance_of(Self::env().caller()) - tokens);
            self.balances.insert(to, self.balance_of(to) + tokens);

            // Emit the event
            self.env().emit_event(Transfer {
                from: Self::env().caller(),
                to,
                tokens,
            });

            true
        }

        // The approve function to set the allowance for another account to transfer tokens on your behalf
        #[ink(message)]
        pub fn approve(&mut self, spender: AccountId, tokens: balance::Balance) -> bool {
            // Set the allowance
            self.allowances.insert((Self::env().caller(), spender), tokens);

            // Emit the event
            self.env().emit_event(Approval {
                owner: Self::env().caller(),
                spender,
                tokens,
            });

            true
        }

        // The transfer from function to transfer tokens on behalf of another account
        #[ink(message)]
        pub fn transfer_from(&mut self, from: AccountId, to: AccountId, tokens: balance::Balance) -> bool {
            // Validate the transfer amount and allowance
            if tokens > self.allowance_of((from, Self::env().caller())) || tokens > self.balance_of(from) {
                return false;
            }

            // Update the balances
            self.balances.insert(from, self.balance_of(from) - tokens);
            self.balances.insert(to, self.balance_of(to) + tokens);

            // Update the allowance
            self.allowances.insert((from, Self::env().caller()), self.allowance_of((from, Self::env().caller())) - tokens);

            // Emit the event
            self.env().emit_event(Transfer {
                from,
                to,
                tokens,
            });

            true
        }

        // The balance of function to get the balance of an account
        #[ink(message)]
        pub fn balance_of(&self, account: AccountId) -> balance::Balance {
            *self.balances.get(&account).unwrap_or(&0)
        }

        // The allowance of function to get the allowance of an account to transfer tokens on behalf of another account
        #[ink(message)]
        pub fn allowance_of(&self, accounts: (AccountId, AccountId)) -> balance::Balance {
            *self.allowances.get(&accounts).unwrap_or(&0)
        }

        // The total supply of function to get the total supply of the token
        #[ink(message)]
        pub fn total_supply(&self) -> balance::Balance {
            self.total_supply
        }

        // The calculate tokens to purchase function to calculate the amount of tokens to be purchased
        fn calculate_tokens_to_purchase(&self) -> balance::Balance {
            let purchase_amount = Self::env().transferred_balance();
            let total_fees = self.calculate_total_fees(purchase_amount);
            let purchase_amount_after_fees = purchase_amount - total_fees;
            let token_price = self.calculate_token_price(self.total_supply + self.liquidity_pool_balance, self.total_supply, purchase_amount_after_fees);
            let tokens_to_purchase = purchase_amount_after_fees / token_price;
            tokens_to_purchase
        }

        // The calculate purchase amount function to calculate the purchase amount
        fn calculate_purchase_amount(&self, tokens_to_purchase: balance::Balance) -> balance::Balance {
            let token_price = self.calculate_token_price(self.total_supply + self.liquidity_pool_balance, self.total_supply, tokens_to_purchase);
            let purchase_amount_after_fees = token_price * tokens_to_purchase;
            let total_fees = self.calculate_total_fees(purchase_amount_after_fees);
            let purchase_amount = purchase_amount_after_fees + total_fees;
            purchase_amount
        }

        // The calculate sell amount function to calculate the sell amount
        fn calculate_sell_amount(&self, tokens: balance::Balance) -> balance::Balance {
            let token_price = self.calculate_token_price(self.total_supply + self.liquidity_pool_balance, self.total_supply, tokens);
            let sell_amount_before_fees = token_price * tokens;
            let total_fees = self.calculate_total_fees(sell_amount_before_fees);
            let sell_amount = sell_amount_before_fees - total_fees;
            sell_amount
        }

        // The calculate token price function to calculate the token price
        fn calculate_token_price(&self, total_tokens: balance::Balance, tokens: balance::Balance, amount: balance::Balance) -> balance::Balance {
            amount * total_tokens / (tokens * 100 - self.calculate_total_fees(100 * tokens))
        }

        // The calculate total fees function to calculate the total fees
        fn calculate_total_fees(&self, amount: balance::Balance) -> balance::Balance {
            let total_fee_percent = self.developer_fee_percent + self.charity_fee_percent + self.auto_liquidity_fee_percent;
            amount * total_fee_percent / 100
        }

        // The distribute fees function to distribute the fees
        fn distribute_fees(&mut self, tokens_to_purchase: balance::Balance) {
            // Calculate the fees
            let developer_fee = tokens_to_purchase * self.developer_fee_percent / 100;
            let charity_fee = tokens_to_purchase * self.charity_fee_percent / 100;
            let auto_liquidity_fee = tokens_to_purchase * self.auto_liquidity_fee_percent / 100;

            // Transfer the developer fee to the developer
            self.env().extension().transfer(
                self.developer,
                developer_fee,
            ).unwrap();

            // Transfer the charity fee to the charity beneficiary
            self.env().extension().transfer(
                self.charity_beneficiary,
                charity_fee,
            ).unwrap();

            // Add the auto liquidity fee to the liquidity pool balance
            self.liquidity_pool_balance += auto_liquidity_fee;
        }
    }

    // Define the events
    #[ink(event)]
    pub struct Buy {
        #[ink(topic)]
        buyer: AccountId,
        #[ink(topic)]
        tokens: balance::Balance,
        #[ink(topic)]
        price: balance::Balance,
    }

    #[ink(event)]
    pub struct Sell {
        #[ink(topic)]
        seller: AccountId,
        #[ink(topic)]
        tokens: balance::Balance,
        #[ink(topic)]
        price: balance::Balance,
    }

    #[ink(event)]
    pub struct Transfer {
        #[ink(topic)]
        from: AccountId,
        #[ink(topic)]
        to: AccountId,
        #[ink(topic)]
        tokens: balance::Balance,
    }

    #[ink(event)]
    pub struct Approval {
        #[ink(topic)]
        owner: AccountId,
        #[ink(topic)]
        spender: AccountId,
        #[ink(topic)]
        tokens: balance::Balance,
    }
}
11590 chars
300 lines

This smart contract has a constructor function new to initialize the token contract with an initial supply, developer fee percentage, charity fee percentage, auto liquidity fee percentage, charity beneficiary address, and developer address. It also has the following functions:

  • buy: to purchase tokens by sending BNB to the smart contract and receive tokens in return
  • sell: to sell tokens and receive BNB in return
  • transfer: to transfer tokens to another account
  • approve: to set the allowance for another account to transfer tokens on your behalf
  • transfer_from: to transfer tokens on behalf of another account

In addition to the standard BEP20 token functions, this smart contract also has the following features:

  • Developer fee: a percentage of the tokens purchased is sent to the developer's address
  • Charity fee: a percentage of the tokens purchased is sent to the charity beneficiary's address
  • Auto liquidity function: a percentage of the tokens purchased is added to the liquidity pool balance, which can be used to provide liquidity to a decentralized exchange

Note that this is just an example implementation and should not be used in production without proper auditing and testing.

gistlibby LogSnag