1

My task is to divide the dividend sent by owner to the contract to the current token holders.The token holders can come later and redeem their pending amounts, the important point here is that, when a deposit is made that deposit should not be given to people that will hold tokens later than this and the portion of each token holder should remain until he redeem.

This is my code snippet:

struct Account {
        uint256 balance;
        uint256 lastDividends;
    }
mapping (address => Account) accounts;

// ------------------------------------------------------------------------
// Ether fallback function -- works as deposit
// ------------------------------------------------------------------------    
function () external payable {
    totalDividends = totalDividends.add(msg.value);
}

// ------------------------------------------------------------------------
// Token holders can claim their pending dividends using this function
// - the sender address must not be excluded by owner
// ------------------------------------------------------------------------
function claimDividend() public notExcluded {
    uint256 owing = accountDividend(msg.sender);
    if (owing > 0) {
        msg.sender.transfer(owing);
        accounts[msg.sender].lastDividends = totalDividends;
    }
}

// ------------------------------------------------------------------------
// Calculates the pending dividends of the holders
// ------------------------------------------------------------------------    
function accountDividend(address account) internal returns (uint256) {
    soldTokens = (_totalSupply.sub(balances[owner])).sub(excludedTokens);
    return ((totalDividends.sub(accounts[account].lastDividends)).mul(accounts[account].balance)).div(soldTokens);
}

However, this code actually divides each deposit with all sold Tokens but it doesn't keep the share of each token holder's safe. Let's say an owner deposited 100 ethers and there are 10 tokens holded by walletA, 20 tokens holded by walletB, and 40 tokens holded by walletC, now according to above snippet, it will divide add the new deposit to the totalDeposit and it will divide the totalDeposit by sold tokens at the moment when a person make withdraw.

As seen from above example, it has 70 sold tokens at the moment it made the deposit but since the accounts are not updated at that moment so, let's say walletA claims later when two more wallet holding 30 more tokens come. At that very moment, according to above snippet it will divide the total deposit by 100.

My problem is to give share of deposits only to those who are currently present and that deposit is not given to people who become holders later. The late token holders will get portion from next payout.

I am looking forward to design guideline, please? I know I can use loops and divide the deposit to all token holders present at the moment but that will cost me alot of gas. I have written that code snippet too:

// this will accept ether deposits
function deposit() public payable{
    soldTokens = (_totalSupply.sub(balances[owner])).sub(excludedTokens);
    uint256 available = msg.value * scaling;
    dividendPerToken = (available).div(soldTokens);
    if(dividendPerToken == 0)
        dividendPerToken += (available).remainder(soldTokens);
    for(uint i=0; i< holders.length; i++){ 
        address account = holders[i];
        //if(account != owner)
        if(excludedWallets[account] == false)
            dividendBalanceOf[account] += balances[account].mul(dividendPerToken);
    }
}


function withDraw() public returns(bool success){
    uint256 amount = dividendBalanceOf[msg.sender].div(scaling);
    amount += dividendBalanceOf[msg.sender].remainder(scaling);
    dividendBalanceOf[msg.sender] = 0;
    msg.sender.transfer(amount);
    return true;
}
1

This is a non-trivial problem.

You cannot use loops. It's not that the gas will get too large to be practical. The contract will fail completely when the loops get too large and that would be catastrophic.

No widely accepted standard exists at this time. You might look at this proposal: https://github.com/ethereum/EIPs/issues/1726 and this implementation: https://github.com/Roger-Wu/erc1726-dividend-paying-token/blob/master/contracts/DividendPayingToken.sol

Hope it helps.

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.