Crowdbotics
Published in

Crowdbotics

How to Build a Dividend Token With Solidity

Troubleshooting common challenges such as rounding errors, sending duplicate dividends, gas optimization, unfixed total supply, and more.

What is dividend token?

Why use dividend Token?

Problems we tackle in our Dividend token contract

DividendToken.sol

Source
    string public name = "Dividend Token";
string public symbol = "DIV";
uint8 public decimals = 0;
uint256 public totalSupply_ = 1000000;
uint256 totalDividendPoints = 0;
uint256 unclaimedDividends = 0;
uint256 pointMultiplier = 1000000000000000000;
address owner;

struct account{
uint256 balance;
uint256 lastDividendPoints;
}
mapping(address => account) public balanceOf;

Dividend Logic

modifier updateDividend(address investor) {
uint256 owing = dividendsOwing(investor);
if(owing > 0) {
unclaimedDividends = unclaimedDividends.sub(owing);
balanceOf[investor].balance = balanceOf[investor].balance.add(owing);
balanceOf[investor].lastDividendPoints = totalDividendPoints;
}
_;
}
function dividendsOwing(address investor) internal returns(uint256){
uint256 newDividendPoints = totalDividendPoints.sub(balanceOf[investor].lastDividendPoints);
return (balanceOf[investor].balance.mul(newDividendPoints)).div(pointMultiplier);
}
function disburse(uint256 amount) onlyOwner public {
totalDividendPoints = totalDividendPoints.add((amount.mul(pointMultiplier)).div(totalSupply_));
totalSupply_ = totalSupply_.add(amount);
unclaimedDividends = unclaimedDividends.add(amount);
}
new dividend = totalDividendPoints - investor's lastDividnedPoint

investor's dividend = ( investor's balance * new dividend ) / points multiplier
totalDividendPoints += (amount * pointMultiplier ) / totalSupply_
investor's dividend = Total Dividend / investor’s balance

Testing Dividend Contract

it('dividend Test' , async() => { 
await this.tokenInstance.transfer(web3.eth.accounts[1],100000, {from : web3.eth.accounts[0]});
await this.tokenInstance.disburse(100000);
await this.tokenInstance.transfer(web3.eth.accounts[2],100000, {from : web3.eth.accounts[1]});
const investor_1_balance = await this.tokenInstance.balanceOf(web3.eth.accounts[1]);
const investor_2_balance = await this.tokenInstance.balanceOf(web3.eth.accounts[2]);
const totalSupply = await this.tokenInstance.totalSupply_();
assert.equal( totalSupply, 1100000);
assert.equal(investor_1_balance, 10000);
assert.equal(investor_2_balance, 100000);
})

Conclusion

Notes & suggestions-

Starting a new blockchain project, or looking for a Solidity developer?

--

--

The fastest way to build your next app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store