3

I'm practicing How to Build a Staking Dapp example in Alchemy. In Staker.sol, there's a withdraw function which hasn't a payable keyword. But it does work. Isn't it necessary to use 'payable' when transferring eth?

function withdraw() public withdrawlDeadlineReached(true) claimDeadlineReached(false) notCompleted {
    require(balances[msg.sender] > 0 , "You have no balance to withdraw!");
    uint256 individualBalance = balances[msg.sender];
    uint256 indBalanceReward = individualBalance + ((block.timestamp - depositTimestamps[msg.sender]) * rewardRatePerBlock);
    balances[msg.sender] = 0;
(bool sent, bytes memory data) = msg.sender.call{value: indBalanceReward}("");
require(sent, "RIP, withdrawl failed :( ");

}

Shift_that
  • 375
  • 3
  • 10

3 Answers3

3

You need the payable modifier when a function you write intends to receive ether (e.g. deposit(), receive(), fallback()...etc). Your withdraw function is not intended to receive ether, so no payable modifier is necessary. And no, it isn't necessary to use payable when transferring ether.

See: payable() function In solidity

Yongjian P.
  • 4,170
  • 1
  • 3
  • 10
1

you should convert msg.sender to address payable:

take a look at the doc

The global variables tx.origin and msg.sender have the type address instead of address payable. One can convert them into address payable by using an explicit conversion, i.e., payable(tx.origin) or payable(msg.sender).

(bool sent, bytes memory data) = payable(msg.sender).call{value: indBalanceReward}("");
Javier Marchetti
  • 1,217
  • 3
  • 12
0

To further clear your understanding of this a similar question like this was asked here. It explain the difference between the two.