I am trying to give funds to different address stored on the contract by sending values to the payable function, but instead the funds are taken from the contracts balance not the senders sent amount. This seems to happens when I return the surplus back to sender. Any ideas how to fix it

uint256 public amount= 64000000000000000;
function giveAwards(uint256[] memory _tokens) external onlyOwner payable {
    require(((_tokens.length * award) <= msg.value ), "Failed amount sent is not enough.");
    uint256 remaining = 0;
    for (uint256 i = 0; i < _tokens.length; i++) {
      uint256 token = _tokens[i];

      remaining = msg.value.sub(amount);
      (bool success,) = payable(ownerOf(token)).call{value : amount}("");
      require(success, "-> Payout transfer failed.");
      payed[i] = token;    

 function _surplus(uint256 _amount) private {
    if (_amount > 0) {
      (bool success,) = msg.sender.call{value : _amount}("");
      require(success, "Surplus transfer failed.");

1 Answer 1


You initialise uint256 remaining = 0, and then set remaining = msg.value.sub(amount) in the loop. But that means that in the second iteration of the loop, you lost the amount you deducted in the first iteration. (because remaining would just be set to msg.value.sub(amount) again - thereby losing the amount you already deducted.)

So instead, what I would do is, initially initialize outside the loop remaining = msg.value. Then, inside the loop, change remaining to be remaining.sub(amount). This way you'll deduct the correct amount.

  • 1
    Yes it seems that was the case . Thank you
    – ramon22
    Commented Oct 19, 2021 at 3:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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