0

I'm trying to code a transfer function that automatically sends tokens to a second address taking a specific percentage from the original sent value. What I wrote:

  address public _ExtAddress;

  function setExtAddress(address _address) onlyOwner public {
    _ExtAddress = _address;
  }

  function setPercentage(uint256 value) onlyOwner public {
    percentage = value;
  }

  function findPercentage(uint256 amount) public view returns (uint256) {
    uint256 percentValue = (amount / 100) * percentage;
    return percentValue;
  }

  function transfer(address to, uint256 value) public returns (bool) {
    require(value <= _balances[msg.sender]);

    uint256 tokensToAddress = findPercentage(value);
    uint256 tokensToTransfer = value.sub(tokensToAddress);

    _balances[msg.sender] = _balances[msg.sender].sub(value);
    _balances[to] = _balances[to].add(tokensToTransfer);

    emit Transfer(msg.sender, to, tokensToTransfer);
    emit Transfer(msg.sender, _ExtAddress, tokensToAddress);
    return true;
  }

Testing it in remix, the output is:

 status     0x1 Transaction mined and execution succeed
 transaction hash   0x7d19e3fac8581083c75b3d04b3448daa2ac7d8cb76de56d9aae5cb2e70418018
 from   0xca35b7d915458ef540ade6068dfe2f44e8fa733c
 to     Test.transfer(address,uint256) 0x692a70d2e424a56d2c6c27aa97d1a86395877b3a
 gas    3000000 gas

 transaction cost   39344 gas 
 execution cost     16344 gas 
 hash   0x7d19e3fac8581083c75b3d04b3448daa2ac7d8cb76de56d9aae5cb2e70418018
 input  0xa90...5e100
 decoded input  {
    "address to": "0xdD870fA1b7C4700F2BD7f44238821C26f7392148",
    "uint256 value": {
        "_hex": "0x05f5e100"
    }
}
 decoded output     {
    "0": "bool: true"
}
 logs   [
    {
        "from": "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
        "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
        "event": "Transfer",
        "args": {
            "0": "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c",
            "1": "0xdD870fA1b7C4700F2BD7f44238821C26f7392148",
            "2": "99000000",
            "from": "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c",
            "to": "0xdD870fA1b7C4700F2BD7f44238821C26f7392148",
            "value": "99000000",
            "length": 3
        }
    },
    {
        "from": "0x692a70d2e424a56d2c6c27aa97d1a86395877b3a",
        "topic": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
        "event": "Transfer",
        "args": {
            "0": "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c",
            "1": "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C",
            "2": "1000000",
            "from": "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c",
            "to": "0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C",
            "value": "1000000",
            "length": 3
        }
    }
]
 value  0 wei

As you can see in the output there are two different Transfer event; the percentage is set to 1% and the amount transferred is 100000000. The hardcoded address that should receive the percentage is 0x14723A09ACff6D2A60DcdF7aA4AFf308FDDC160C, and in logs it is actually receiving the 1%, but if I call the balanceOf function in remix it says it has 0 tokens, while the other address 0xdD870fA1b7C4700F2BD7f44238821C26f7392148 has exactly 99000000 as it should have. What am I doing wrong? Why the transfer event occurs but there are no tokens transferred to the second address? Thank you

0

Your contract never assigns extra tokens to your hardcoded address.

I think you are a bit mixed up about what events are. They do not actually perform and functionality, they only emit an event which can be read. You can always remove all events from functions and the actual functionality will stay the same. Events are only useful for notifying backend systems of what is happening inside the contract.

So what you need is to assign tokens to the _ExtAddress. So basically _balances[_ExtAddress] = _balances[_ExtAddress].add(tokensToAddress);

Be wary of rounding issues; you may end up accidentally minting or losing tokens when you have rounding issues. For example 4 / 3 = 1 as Solidity doesn't have native decimal numbers.

  • I knew it was a silly mistake I was doing... Thanks! – AlxMrx Jun 15 at 16:19
  • Thinking about what you mentioned for rounding issues, how about doing percentage with basis points (where 1% is 100)? I'm also looking to implement a ceil function for better rounding up. What do you think? – AlxMrx Jun 15 at 18:01
  • I'm not sure what you mean with basis points but the idea remains the same: you can't store decimal values. They can be present inside calculations (4/3 * 3 = 4) but you can't see them. So, yes, if you "need" to use decimals at least use ceil/floor functions to be sure which end you get as result. – Lauri Peltonen Jun 15 at 18:20
  • Or, well, floor function is implemented "by default" already, so you only need to implement ceil if you need such :) – Lauri Peltonen Jun 15 at 18:29
  • A basis point is one hundredth of a percent or equivalently one ten thousandth; so one percent is 100 and the percentage is calculated on 10000 instead of the hundred. In this way I should reduce the risk of issues coming from rounding. – AlxMrx Jun 15 at 18:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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