0

I am trying to send pay a dividend token contract Ether from another contract using the deposit() function in the contract below. I have found conflicting answers based on different compiler versions.

Below is the token contract that accepts deposits which are paid out as dividends:

pragma solidity ^0.4.19;

contract RobustDividendToken {

    string public name = "Robust Dividend Token";
    string public symbol = "DIV";
    uint8 public decimals = 18;

    uint256 public totalSupply = 1000000 * (uint256(10) ** decimals);

    mapping(address => uint256) public balanceOf;

    function RobustDividendToken() public {
        // Initially assign all tokens to the contract's creator.
        balanceOf[msg.sender] = totalSupply;
        Transfer(address(0), msg.sender, totalSupply);
    }

    uint256 public scaling = uint256(10) ** 8;

    mapping(address => uint256) public scaledDividendBalanceOf;

    uint256 public scaledDividendPerToken;

    mapping(address => uint256) public scaledDividendCreditedTo;

    function update(address account) internal {
        uint256 owed =
            scaledDividendPerToken - scaledDividendCreditedTo[account];
        scaledDividendBalanceOf[account] += balanceOf[account] * owed;
        scaledDividendCreditedTo[account] = scaledDividendPerToken;
    }

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    mapping(address => mapping(address => uint256)) public allowance;

    function transfer(address to, uint256 value) public returns (bool success) {
        require(balanceOf[msg.sender] >= value);

        update(msg.sender);
        update(to);

        balanceOf[msg.sender] -= value;
        balanceOf[to] += value;

        Transfer(msg.sender, to, value);
        return true;
    }

    function transferFrom(address from, address to, uint256 value)
        public
        returns (bool success)
    {
        require(value <= balanceOf[from]);
        require(value <= allowance[from][msg.sender]);

        update(from);
        update(to);

        balanceOf[from] -= value;
        balanceOf[to] += value;
        allowance[from][msg.sender] -= value;
        Transfer(from, to, value);
        return true;
    }

    uint256 public scaledRemainder = 0;

    function deposit() public payable {
        // scale the deposit and add the previous remainder
        uint256 available = (msg.value * scaling) + scaledRemainder;

        scaledDividendPerToken += available / totalSupply;

        // compute the new remainder
        scaledRemainder = available % totalSupply;
    }

    function withdraw() public {
        update(msg.sender);
        uint256 amount = scaledDividendBalanceOf[msg.sender] / scaling;
        scaledDividendBalanceOf[msg.sender] %= scaling;  // retain the remainder
        msg.sender.transfer(amount);
    }

    function approve(address spender, uint256 value)
        public
        returns (bool success)
    {
        allowance[msg.sender][spender] = value;
        Approval(msg.sender, spender, value);
        return true;
    }

}

My contract works except for this operation. If I were to simple send a random address with: randomaddr.transfer(this.balance); then we have no problems.

However, when I try TokenContractAddress.call.value(this.balance)(); or I try TokenContractAddress.deposit.value(this.balance)(); the Tx fails.

I have tried importing the contract and some other syntax too, but I get the same error. What is the best way to make it work?

2

The following won't succeed because the target contract doesn't define a payable fallback function:

TokenContractAddress.call.value(this.balance)();

Your other attempt is correct, assuming TokenContractAddress is a variable of type RobustDividendToken that points to the deployed RobustDividendToken contract:

TokenContractAddress.deposit.value(this.balance)();

If this is failing, please provide the full code that you're using and describe how you're deploying each contract and how TokenContractAddress gets its value.

Here's a test contract I made that is able to successfully call RobustDividendToken's deposit function:

contract Test {
    RobustDividendToken token;

    function Test(RobustDividendToken _token) public {
        token = _token;
    }

    function deposit() public payable {
        token.deposit.value(msg.value)();
    }
}

I deployed RobustDividendToken via Remix, then copied its address and deployed Test passing that address as a constructor parameter. (Be sure to pass the address as a quoted string.) Then I set the value field in Remix to a non-zero value and called deposit on Test. The transaction succeeded.

|improve this answer|||||
  • I couldn't get that to compile. What does RobustDividendToken token do? Should I be importing RobustDividendToken above? I just have TokenContract = 0x2274cbe6BC66a2Ce7EeBcC80b6F8162E73F78c76; now in my contract's constructor and TokenContract is an address type. I think this must be the thing I'm messing up. – TrumpPaiPence Mar 7 '18 at 23:29
  • 1
    Yes, you need RobustDividendToken available somehow (defined in the same file, imported, or just defined as an interface). Then you can do RobustDividendToken token = 0x2274cb.... – user19510 Mar 7 '18 at 23:33
  • 1
    See programtheblockchain.com/posts/2018/02/02/… if you choose to use an interface. – user19510 Mar 7 '18 at 23:34
  • Read that before posting, but I suspect it's the right answer. :-) Hopefully sleep helps. Great site. There is a lot of fragmented documentation on the syntax. I understand mappings and its one way nature now from the dividend contract, so that's a win! – TrumpPaiPence Mar 7 '18 at 23:54
  • Got it to work! I just pasted the RobustDividendToken contract above, and used this: RobustDividendToken public TokenContract = RobustDividendToken(0x2274cbe6BC66a2Ce7EeBcC80b6F8162E73F78c76); and then TokenContract.deposit.value(TokenCommission)(); to ship the Ether over to the dividend contract. – TrumpPaiPence Mar 8 '18 at 0:29

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.