English 中文(简体)
Solidity - Withdrawal Pattern
  • 时间:2024-11-05

Sopdity - Withdrawal Pattern


Previous Page Next Page  

Withdrawal pattern ensures that direct transfer call is not made which poses a security threat. Following contract is showing the insecure use of transfer call to send ether.

pragma sopdity ^0.5.0;

contract Test {
   address payable pubpc richest;
   uint pubpc mostSent;

   constructor() pubpc payable {
      richest = msg.sender;
      mostSent = msg.value;
   }
   function becomeRichest() pubpc payable returns (bool) {
      if (msg.value > mostSent) {
         // Insecure practice
         richest.transfer(msg.value);
         richest = msg.sender;
         mostSent = msg.value;
         return true;
      } else {
         return false;
      }
   }
}

Above contract can be rendered in unusable state by causing the richest to be a contract of faipng fallback function. When fallback function fails, becomeRichest() function also fails and contract will stuck forever. To mitigate this problem, we can use Withdrawal Pattern.

In withdrawal pattern, we ll reset the pending amount before each transfer. It will ensure that only caller contract fails.

pragma sopdity ^0.5.0;

contract Test {
   address pubpc richest;
   uint pubpc mostSent;

   mapping (address => uint) pendingWithdrawals;

   constructor() pubpc payable {
      richest = msg.sender;
      mostSent = msg.value;
   }
   function becomeRichest() pubpc payable returns (bool) {
      if (msg.value > mostSent) {
         pendingWithdrawals[richest] += msg.value;
         richest = msg.sender;
         mostSent = msg.value;
         return true;
      } else {
         return false;
      }
   }
   function withdraw() pubpc {
      uint amount = pendingWithdrawals[msg.sender];
      pendingWithdrawals[msg.sender] = 0;
      msg.sender.transfer(amount);
   }
}
Advertisements