0

I wrote a smart contract where It should allow to fund contract with some ethereum and erc20 token that I made. Problem is that when I send eth transaction fails. Same as if I try to send my erc20 token.

My token: https://rinkeby.etherscan.io/token/0x8966504a3b07e2cecd4f4bbb3d51566c7127b156

Transactions failed: https://rinkeby.etherscan.io/tx/0x00c7aab231a8e6c2b02ad6db5f3e9cbf7f380e287347402f4e358866ffa40b2c

https://rinkeby.etherscan.io/tx/0xab168ba0357ad55ae7d4f79eac669951e7720cdf6ab29621ead39a58bd35623e

Contract:

pragma solidity ^0.4.23;

import "./ERC20Interface.sol";
//import "./ownership/Ownable.sol";
//import "./ownership/Whitelist.sol";
import "./Ownable.sol";
import "./SafeMath.sol";

contract AirdropContract is Ownable{

    using SafeMath for uint256;

    ERC20Interface token;
    uint256 private amountOfEther;
    uint256 private amountOfFun;

    event DropedEth(address from, address to, uint256 amount);
    event DropedFun(address from, address to, uint256 amount);

    event SentEthToContract(address from, address to, uint256 amount);
    event SentFunToContract(address from, address to, uint256 amount);

    constructor(ERC20Interface _token) public {
        token = _token;
    }

    // assign admin (access to fund contract and airdrop)
    function assignAdmin(address admin_address) public onlyOwner {
        assignAdmin(admin_address);
    }

    // fund contract with eth callback function
    function () public payable ownerAndAdmin{
        amountOfEther = amountOfEther.add(msg.value);
        emit SentEthToContract(msg.sender, address(this), msg.value);
    }

    function sendFunToContract(uint256 amount) public ownerAndAdmin returns(bool success){
        token.transfer(address(this), amount);
        amountOfFun = amountOfFun.add(amount);

        emit SentFunToContract(msg.sender, address(this), amount);
        return true;
    }

    function dropEth(address[] recipients, uint256[] values) public payable ownerAndAdmin  returns(bool success)
    {
        for (uint256 i = 0; i < recipients.length; i++) {
            recipients[i].transfer(values[i]);

            emit DropedEth(address(this), recipients[i], values[i]);
        }

        return true;
    }

    function dropFun(address[] recipients, uint256[] values) public {
        for (uint256 i = 0; i < recipients.length; i++) {
            token.transfer(recipients[i], values[i]);

            emit DropedFun(address(this), recipients[i], values[i]);
        }
    }
}

I used this migration to deploy:

const AirdropContract = artifacts.require("./AirdropContract")

module.exports = function(deployer) {
    deployer.deploy(AirdropContract, 0x8966504a3B07E2cECD4f4bBb3d51566c7127B156);
};

Also my ownable:

pragma solidity ^0.4.23;

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address public owner;
    mapping(address => bool) private admins;

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor() public {
        owner = msg.sender;
    }


    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    modifier ownerAndAdmin() {
        require(msg.sender == owner || admins[msg.sender]);
        _;
    }


    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        if (newOwner != address(0)) {
            owner = newOwner;
      }
    }

    // assign admin (access to fund contract and airdrop)
    function assignAdmin(address admin_address) public onlyOwner {
        require(msg.sender == owner, "wrong address");
        require(!admins[admin_address], "already added");
        admins[admin_address] = true;
    }

    // remove admin (access to fund contract and airdrop)
    function removeAdmin(address admin_address) public onlyOwner {
        require(msg.sender == owner, "wrong address");
        require(admins[admin_address], "not admin yet");
        admins[admin_address] = false;
    }
}

How do I invoke sending the eth and erc20 correctly then? I am trying via MEW.

1

First you have to transfer tokens from your address to the airdrop contract address

In javascript you can do somethink like this

tokenContract.methods.transfer(airdropContract.address, amountTokens)
    .send({ from: accountWithTokens })

You can also use a wallet like MEW to transfer token to the airdrop contract address. You do not have to call your aidrop contract but the token contract.

Actually you function sendFunToContract is wrong

function sendFunToContract(uint256 amount) public ownerAndAdmin returns(bool success){
    token.transfer(address(this), amount);
    amountOfFun = amountOfFun.add(amount);

    emit SentFunToContract(msg.sender, address(this), amount);
    return true;
}

It is sending tokens to itself with token.transfer(address(this), amount). Which will fail if the contract doesn't have enough balance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.