Solidity

由於除法截斷為零,無法空投到多個地址

  • March 21, 2022

我正在 remixIDE 上建構空投智能合約。我想發送空投代幣,這取決於使用者擁有多少權益代幣。當我添加一個使用者時,契約有效並且使用者獲得了 airdropToken。但是當我添加多個使用者時,它不起作用。airdropToken 和 airdropTokenList 的結果一直顯示為 0。

pragma solidity 0.5.17;


contract Airdrop is Ownable{
   using SafeMath for uint256;

   //Vairables
   uint256 BIGNUMBER = 10**18;
   uint256 totalAirdropToken = 10000; 

   address public owner;
   IERC20 public airdropToken;

   uint256 public totalStakeToken; //total of user's stakeToken
   address[] public receiverList; //list of users which owner added
   uint256[] public airdropTokenList; //list of tokens the user will receive
   mapping(address => uint256) public stakeTokens; //user's address -> user's stakeToken
   mapping(address => uint256) public airdropTokens; //user's address -> user's airdropToken

   //Contructor
   constructor(address _airdropTokenAddr) public {
     owner = msg.sender;
     airdropToken = IERC20(_airdropTokenAddr);
   }
   
   //Event
   event Drop(address account, uint256 amount);

   //A function that calculate tokens to give to a user
   function calculate(address _account) private view returns(uint256) {
     return (stakeTokens[_account]).div(totalStakeToken).mul(totalAirdropToken).mul(BIGNUMBER);
   }

   //owner saves user's address and their amount of stakeToken
   function saveUserTokens(address[] memory _recipients, uint256[] memory _amount) public onlyOwner {
       require(_recipients.length == _amount.length);
       receiverList = _recipients;

       for (uint i = 0; i < receiverList.length; i++) {
           require(_recipients[i] != address(0));
           totalStakeToken += _amount[i];
           stakeTokens[receiverList[i]] = _amount[i];
       }
   }

   //owner saves the calculated airdropToken to mapping(airdropTokens)
   function sendAirdropToken() public onlyOwner {
     for(uint i=0; i<receiverList.length; i++){
         airdropTokenList.push(calculate(receiverList[i]));
         airdropTokens[receiverList[i]] = calculate(receiverList[i]);
     }
   }

   //user can get the airdropToken by calling this function
   function drop() public {
     IERC20(airdropToken).transfer(msg.sender, airdropTokens[msg.sender]);

     emit Drop(msg.sender, airdropTokens[msg.sender]);
   }

   function destroy() public onlyOwner {
     IERC20(airdropToken).transfer(msg.sender, IERC20(airdropToken).balanceOf(address(this)));

     selfdestruct(msg.sender);
   }

   function airdropOwnerBalance() public view returns (uint256) {
     return IERC20(airdropToken).balanceOf(address(this));
   }

   function airdropUserBalance(address _account) public view returns (uint256) {
     return IERC20(airdropToken).balanceOf(_account);
   }
}

問題出在calculate功能上

(stakeTokens[_account]).div(totalStakeToken).mul(totalAirdropToken).mul(BIGNUMBER)

如果totalStakeToken > stakeTokens[_account]為真,則(stakeTokens[_account]).div(totalStakeToken)由於整數除法截斷而為零。

可能你想做這樣的事情:

(stakeTokens[_account]).mul(totalAirdropToken).mul(BIGNUMBER).div(totalStakeToken)

引用自:https://ethereum.stackexchange.com/questions/124100