Crowdsale send BNB fail

I am trying to create an AllowanceCrowdsale and have some issues.

The one is with the price, i want to have something like 1 BNB = 10000 MyToken.
MyToken has 8 decimals.
I’ve read the tutorial but i still don’t get it.
Even if i have a rate of 1 it still provides way to much of MyToken.
I have tried multiple variants but i can’t understand what i’m doing wrong.
I have tried dividing as you can see below : .div(10**8) but it was not ok.

Another issue that i have is that when someone sends BNB to my crowdsale contract address it returns an error (A Status code indicating if the top-level call succeeded or failed (applicable for Post BYZANTIUM blocks only).
If I (the contract creator of both the token and the crowdsale contract) send BNB to the crowdsale contract it works fine.
I am using an allowance crowdsale and i have approved spending from the token’s contract to the crowdsale contract.

    // contracts/SimpleCrowdsale.sol
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.4.23;

    import "./token/IERC20.sol";
    import "https://github.com/ConsenSysMesh/openzeppelin-solidity/blob/master/contracts/crowdsale/emission/AllowanceCrowdsale.sol";

    contract MyCrowdsale is Crowdsale, AllowanceCrowdsale  {
        constructor(
            uint256 rate, // Number of token units a buyer gets per wei
            address  wallet, // Address where funds are collected
            ERC20 token,
            address tokenWallet//  // Address holding the tokens, which has approved allowance to the crowdsale
        )
            AllowanceCrowdsale(tokenWallet)  
            Crowdsale(rate, wallet, token)
            public
        {

        }
        
        /**
       * @dev Override to extend the way in which ether is converted to tokens.
       * @param _weiAmount Value in wei to be converted into tokens
       * @return Number of tokens that can be purchased with the specified _weiAmount
       */
        function _getTokenAmount(uint256 _weiAmount)
            internal view returns (uint256)
        {
            return _weiAmount.mul(rate).div(10**8);
            //return _weiAmount.mul(rate);
        }
        
        
        function changeRate(uint256 _rate) public {
            rate = _rate;
        }
    }
1 Like

Hey, It looks like ok, so could you please show the failed transaction hash?

Thank you for your answer.
Here you can see a list with multiple transactions:

Maybe i have interpreted the contructor incorrectly and on creation i pass invalid addresses:

  • wallet = i have tried both with the same address as the token wallet and with an entirely new address
  • token = address of MyToken
  • tokenWallet = address where all of MyTokens are located; the address from where i approve the crowdsale contract to spend some tokens
1 Like

The problem may be that for the token i have a IBEP20 token compiled with solidity 0.6.0 ?
Is that correct ?
The crowdsale i see that it is for ERC20. Does it need to be adapted to IBEP20 ?
Thanks.

1 Like

Hi @vady,

Welcome to the community :wave:

You may want to import from OpenZeppelin Contracts for IERC20 and Crowdsale:

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v2.5.1/contracts/token/ERC20/ERC20.sol

The Crowdsale documentation can be found here:
https://docs.openzeppelin.com/contracts/2.x/crowdsales

I recommend testing locally first and writing unit tests. See: Simple ERC20 Crowdsale

I think i found the issue. It was a problem with gas limit, if i leave it default 21000 it fails, if i set it to 210000 it works. Is this normal ? I figure it’s like this because the crowdsale contract needs to get the tokens from the token contract, is that correct ?

Thanks

1 Like

Hi @vady,

Gas limit would be the culprit in this instance.

I assume you were calling buyTokens rather than just sending currency to the Crowdsale.

fallback function DO NOT OVERRIDE Note that other contracts will transfer funds with a base gas stipend of 2300, which is not enough to call buyTokens. Consider calling buyTokens directly when purchasing tokens from a contract.
https://docs.openzeppelin.com/contracts/2.x/api/crowdsale#Crowdsale-fallback--

Thank you for answer.
I was not calling buyTokens function, i was directly sending funds.
Could you please explain a bit more, i am a little bit confused.

How much should calling buyTokens cost and how much sending directly ?
Which is the preferred method ?
When is the fallback called ?

Thank you

1 Like

Hi @vady,

In your dapp you should use buyTokens rather than sending Ether to the contract via the fallback as not enough gas may be sent for the transaction, unless you either specify the gas or the users manually increase the gas.

I am not sure how much difference there is in gas cost.
You can test the gas on a public testnet or create unit tests and use a gas reporter.

1 Like