-2

I tried writing a smart contract, but I can't test it on testnet. Also, I am concerned about its vulnerabilities as I am not so experienced with how smart contracts behave in some situations. So here is my code:

pragma solidity ^0.4.15;
contract ERC20 {
    function balanceOf(address who) public constant returns (uint256);
    function transferFrom(address from,address to, uint256 value) public returns (bool);
}

contract MyContract {
    address[] funders = [0x0,0x1,0x2];
    address target = 0x3;       //address to send raised fund
    address gasStation = 0x4;    
    ERC20 token = ERC20(0x44197A4c44D6A059297cAf6be4F7e172BD56Caaf);     // token contract

    uint raisedFund = 0;
    mapping (address => uint) depositAmount;     // deposit amount of whitelisted addresses
    mapping (address => uint) tokenAmount;       // expected amount of token when distributing
    mapping (address => bool) ready;      // marks if the address owner is ready
    bool funding = true;        // marks if the fundraising is still going
    uint num_of_ready = 0;

    function MyContract() payable {
        if(funding)         // will ignore the transaction when funding is over.
            updateRaisedFund();
    }

    function updateRaisedFund() internal {
        for(uint i = 0;i < funders.length;i++){ 
            if(funders[i] == msg.sender){       // will ignore every deposit from other address
                raisedFund += msg.value;
                depositAmount[msg.sender] += msg.value;
                break;
            }
        }
    }

    modifier whiteListed {
        bool inList = false;
        for(uint i = 0;i < funders.length;i++){ 
            if(funders[i] == msg.sender){
                inList = true;
            }
        }
        require(inList);     
        _;
    }

    function withdrawEth() whiteListed {
        uint minAmount = depositAmount[msg.sender]; 
        if(minAmount > 5 * (10**15) && funding){   // if the funding period is over, you can't withdraw
            msg.sender.transfer(minAmount - 5 * (10**15)); // 0.005 for gas fee
            raisedFund -= depositAmount[msg.sender];
            depositAmount[msg.sender] = 0;
        }
    }

    function readyToGo() whiteListed {
        if(ready[msg.sender] == false){
            ready[msg.sender] = true;
            num_of_ready ++;
            if(num_of_ready == funders.length){
                funding = false;
            }
        }
    }

    modifier allReady {
        require(funding == false);
        _;
    }

    function sendTheFund() allReady {
        raisedFund -= funders.length*(5**15);   //// 0.005ETH perfor token withdrawal
        target.transfer(raisedFund); 

        // setting up expected token return

    }

    modifier tokenCame{
        require(token.balanceOf(this) > 0);
        _;
    }

    function distributeToken() tokenCame{   // withdraws token to all funders
        for(uint i = 0;i < funders.length;i++){
            tokenAmount[funders[i]] = token.balanceOf(this) * (depositAmount[funders[i]] - 5**15)  / (raisedFund);
        }
        for(i = 0;i < funders.length;i++){
            token.transferFrom(this,funders[i],tokenAmount[funders[i]]);
        }
        gasStation.transfer(this.balance);      // withdraw leftover to gasStation
    }
}

Can you point out the vulnerabilities and mistakes in my code? And how to avoid it?

1

Well... you should really specify the visibility of your functions and at least include safe math.

look at the compiler outputs: https://ethfiddle.com/qI7KPs6GVW

| improve this answer | |

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