Skip to content

Instantly share code, notes, and snippets.

@jessiepathfinder
Created April 15, 2021 04:40
Show Gist options
  • Save jessiepathfinder/de1bcdd502cc57580168f4800a209560 to your computer and use it in GitHub Desktop.
Save jessiepathfinder/de1bcdd502cc57580168f4800a209560 to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.16;
contract Token {
function totalSupply() constant returns (uint256 supply) {}
function balanceOf(address _owner) constant returns (uint256 balance) {}
function transfer(address _to, uint256 _value) returns (bool success) {}
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {}
function approve(address _spender, uint256 _value) returns (bool success) {}
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {}
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract DividendPayingTokenInterface {
function dividendOf(address _owner) view returns(uint256) {}
function distributeDividends() payable {}
function withdrawDividend() {}
event DividendsDistributed(address indexed from, uint256 weiAmount);
event DividendWithdrawn(address indexed to, uint256 weiAmount);
function withdrawableDividendOf(address _owner) view returns(uint256) {}
function withdrawnDividendOf(address _owner) view returns(uint256) {}
function accumulativeDividendOf(address _owner) view returns(uint256) {}
}
contract DividendsPayingToken is Token, DividendPayingTokenInterface {
//SafeMath: add two numbers
function add(uint256 a, uint256 b) pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
//SafeMath: subtract two numbers
function sub(uint256 a, uint256 b) pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
//SafeMath: multiply two numbers
function mul(uint256 a, uint256 b) pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
//SafeMath: divide two numbers
function div(uint256 a, uint256 b) pure returns (uint256) {
require(b > 0, "SafeMath: division overflow");
return a / b;
}
//SafeMath: add two numbers
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a));
return c;
}
//SafeMath: subtract two numbers
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a));
return c;
}
//SafeCast: converts an signed int256 into a unsigned uint256.
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
//SafeCast: converts an unsigned uint256 into a signed int256.
function toInt256(uint256 value) internal pure returns (int256) {
require(value < 2**255, "SafeCast: value doesn't fit in an int256");
return int256(value);
}
//transfers tokens between your wallet and another wallet
function transfer(address _to, uint256 _value) returns (bool success) {
uint256 sender_balance = balances[msg.sender];
uint256 reciever_balance = balances[_to];
if (sender_balance >= _value && add(reciever_balance, _value) > reciever_balance) {
balances[msg.sender] = sub(sender_balance, _value);
balances[_to] = add(reciever_balance, _value);
int256 _magCorrection = toInt256(mul(magnifiedDividendPerShare, _value));
magnifiedDividendCorrections[msg.sender] = add(magnifiedDividendCorrections[msg.sender], _magCorrection);
magnifiedDividendCorrections[_to] = sub(magnifiedDividendCorrections[_to], _magCorrection);
Transfer(msg.sender, _to, _value);
return true;
} else { return false; }
}
//transfers tokens from a wallet you are approved to send tokens from
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
uint256 allowed_sender = allowed[_from][msg.sender];
uint256 sender_balance = balances[_from];
uint256 reciever_balance = balances[_to];
if (balances[_from] >= _value && allowed_sender >= _value && add(reciever_balance, _value) > reciever_balance) {
balances[_to] = add(reciever_balance, _value);
balances[_from] = sub(sender_balance, _value);
allowed[_from][msg.sender] = sub(allowed_sender, _value);
int256 _magCorrection = toInt256(mul(magnifiedDividendPerShare, _value));
magnifiedDividendCorrections[_from] = add(magnifiedDividendCorrections[_from], _magCorrection);
magnifiedDividendCorrections[_to] = sub(magnifiedDividendCorrections[_to], _magCorrection);
Transfer(_from, _to, _value);
return true;
} else { return false; }
}
//gets the balance of a wallet
function balanceOf(address _owner) constant returns (uint256 balance) {
return balances[_owner];
}
//approves someone to send your tokens from your wallet
function approve(address _spender, uint256 _value) returns (bool success) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
//check your remaining allowance for sending tokens from someone else's wallet
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
//data storage
mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed;
uint256 public totalSupply;
//Dividends distributer begins here
//more data storage
uint256 internal magnifiedDividendPerShare;
mapping(address => int256) internal magnifiedDividendCorrections;
mapping(address => uint256) internal withdrawnDividends;
uint256 constant internal magnitude = 2**128;
//distributes dividends to all shareholders
function distributeDividends() public payable {
require(totalSupply > 0);
if (msg.value > 0) {
magnifiedDividendPerShare = add(magnifiedDividendPerShare, div(mul(msg.value, magnitude), totalSupply));
emit DividendsDistributed(msg.sender, msg.value);
}
}
//withdraw dividends
function withdrawDividend() public {
uint256 _withdrawableDividend = withdrawableDividendOf(msg.sender);
if (_withdrawableDividend > 0) {
withdrawnDividends[msg.sender] = add(withdrawnDividends[msg.sender], _withdrawableDividend);
emit DividendWithdrawn(msg.sender, _withdrawableDividend);
(msg.sender).transfer(_withdrawableDividend);
}
}
//check how much unpaid dividends a shareholder have
function dividendOf(address _owner) public view returns(uint256) {
return withdrawableDividendOf(_owner);
}
//check how much unpaid dividends a shareholder have
function withdrawableDividendOf(address _owner) public view returns(uint256) {
return sub(accumulativeDividendOf(_owner), withdrawnDividends[_owner]);
}
//check how much dividends a shareholder have withdrawn
function withdrawnDividendOf(address _owner) public view returns(uint256) {
return withdrawnDividends[_owner];
}
//check how much dividends a shareholder have earned
function accumulativeDividendOf(address _owner) public view returns(uint256) {
return div(toUint256(add(toInt256(mul(magnifiedDividendPerShare, balances[_owner])), magnifiedDividendCorrections[_owner])), magnitude);
}
}
contract EUBIDividendDistributor is DividendsPayingToken {
string public name;
uint8 public decimals;
string public symbol;
string public version = 'H1.0';
Token eubi;
//constructor
function EUBIDividendDistributor() public {
address tokenaddr = 0x8afa1b7a8534d519cb04f4075d3189df8a6738c1;
eubi = Token(tokenaddr);
totalSupply = 0;
name = "EUB Insurance Mutual Shareholding";
decimals = 12;
symbol = "EIMS";
}
//converts EUBI tokens into EIMS tokens
function mint(uint256 value) public {
eubi.transferFrom(msg.sender, address(this), value);
magnifiedDividendCorrections[msg.sender] = sub(magnifiedDividendCorrections[msg.sender], toInt256(mul(magnifiedDividendPerShare, value)));
balances[msg.sender] = add(balances[msg.sender], value);
totalSupply = add(totalSupply, value);
}
//converts EIMS tokens into EUBI tokens
function burn(uint256 value) public {
eubi.transfer(msg.sender, value);
magnifiedDividendCorrections[msg.sender] = add(magnifiedDividendCorrections[msg.sender], toInt256(mul(magnifiedDividendPerShare, value)));
balances[msg.sender] = sub(balances[msg.sender], value);
totalSupply = sub(totalSupply, value);
}
//approves and then calls the receiving contract
function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
if(!_spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData)) { throw; }
return true;
}
//handles payments to contract
function() external payable {
distributeDividends();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment