I am building a function that will payout dividends based on the percentage of tokens owned.

    function simulateRent() public payable{
        uint256 rent_received = msg.value;
        for (uint i = 0; i < ownersCount; i++) {
            uint256 calculateRent = balanceOf(address(owners[i]))*(rent_received)/_totalSupply;

This function seems to work when I have simple numbers, e.g. if total supply is 1M and each person owns half, then the msg.amount will be split in half and divided equally. However, I encounter problems when dealing with more than 2 owners and especially when their number of tokens owned isn't easily divisible.

I was wondering how can I make this calculation?

For context: Total supply is 1M*e18 (18 decimals). Incoming payable amount will be around 1 ETH (it can be less than 1 ETH).


1 Answer 1


A way to solve this problem:

         /       \
       yes        no
       /           \
calculateRent   introduce 'x' so that
                input - x = factor

A factor is a number that divides the given number without any remainder.

  • Verify that balanceOf(address(owners[i]))*(rent_received) is divisible by _totalSupply, if they are not, make them divisible.

  • This will be achieved by calculating the modulus of the mentioned inputs. If the output is 0, then you are good to go, otherwise, one of the inputs will have to be changed.

  • Knowing that the factors of _totalSupply is dependent on balanceOf(address(owners[i])) and rent_received, you might consider adding a new variable x to the formula, the factor will look something like this:

factor = balanceOf(address(owners[i])) * (rent_received - x) 
                                                       /* ^
                                                          |___ will be substracted from the amount
                                                               received so it will be equal to the 
                                                               closest factor*/

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.