1

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 Answers 2

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.

5
  • 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. Commented Mar 7, 2018 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.... Commented Mar 7, 2018 at 23:33
  • 1
    See programtheblockchain.com/posts/2018/02/02/… if you choose to use an interface. Commented Mar 7, 2018 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! Commented Mar 7, 2018 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. Commented Mar 8, 2018 at 0:29
0

I couldn't make the syntax from user19510 work.

Let me answer this specific question

How do You Send Ether to Another Contract's Payable Function?

with a generic example:

If you have a contract called A, with a function foo() that is payable. And you have a contract called B with a function boo() that wants to call this function foo from Contract A and needs to send ether to it, then

function boo() public payable { a.foo{value: msg.value}(); } 

Please make sure that boo is also payable.

And note a is a variable of Contract Type A.

The round brackets () after the curly brackets {} take the arguments of your function foo.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.