pragma solidity ^0.4.26;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
contract ClaimableToken {
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address _owner) constant public returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address _to, uint256 _value) public returns (bool);
}
contract ERC20Basic {
uint256 public totalSupply;
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address who) public constant returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) public returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
}
contract ERC20 is ERC20Basic {
function allowance(address owner, address spender) public constant returns (uint256);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) public returns (bool);
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
*
* This is internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public returns (bool);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract MTFinance is ERC20 {
using SafeMath for uint256;
address owner = msg.sender;
mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed;
string public constant name = "MTFinance";
string public constant symbol = "MTF";
uint public constant decimals = 18;
/**
* @dev Amount of tokens in existence.
*/
uint256 public totalSupply = 20000e18;
/**
* @dev Amount of tokens distributed to investors.
*/
uint256 public totalDistributed = 0;
/**
* @dev Minimum amount of ETH to be invested.
*/
uint256 public constant MIN_CONTRIBUTION = 1 ether / 100; // 0.01 Ether
/**
* @dev 20 Token per ETH is configured by default which can me amended
*/
uint256 public tokensPerEth = 20e18;
/**
* @dev The minimum supply can go up to 5000 after burn
*/
uint256 private minimumSupply = 5000e18;
/**
* @dev Burn rate for transfers, initially set at 0,
* which can be changed based on community voting.
*/
uint burnRate=0; // 10 =1%
/**
* @dev Event gets fired when the token burn rate changes
*/
event TokenBurnRateUpdated(uint burnRate);
/**
* @dev Transfet Event gets emmited when the token transfer gets invoked
*/
event Transfer(address indexed _from, address indexed _to, uint256 _value);
/**
* @dev Approval Event gets emmited when the token approval gets invoked
*/
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
/**
* @dev Distr Event gets emmited when the token gets distributed to investors, including airdrops
*/
event Distr(address indexed to, uint256 amount);
/**
* @dev DistrFinished Event gets emmited when the contract owner ends the presale
*/
event DistrFinished();
/**
* @dev Airdrop Event gets emmited when airdrop happens
*/
event Airdrop(address indexed _owner, uint _amount, uint _balance);
/**
* @dev This event gets emmited when ETH per token is updated
*/
event TokensPerEthUpdated(uint _tokensPerEth);
/**
* @dev This event gets emmited when owner burns the tokens.
*/
event Burn(address indexed burner, uint256 value);
/**
* @dev This flags value will be changed once presale distribution ends.
*/
bool public distributionFinished = false;
modifier canDistr() {
require(!distributionFinished);
_;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
/**
* @dev This function is the default constructor which loads on initialization.
*
*/
constructor () public {
owner = msg.sender;
distr(owner, totalDistributed);
}
/**
* @dev This function can be called to transfer the ownership of the contract.
*
*/
function transferOwnership(address newOwner) onlyOwner public {
if (newOwner != address(0)) {
owner = newOwner;
}
}
/**
* @dev This function can be called in the event of presale End.
*
*/
function finishDistribution() onlyOwner canDistr public returns (bool) {
distributionFinished = true;
emit DistrFinished();
return true;
}
/**
* @dev This function distributes the tokens to the investors.
*
*/
function distr(address _to, uint256 _amount) canDistr private returns (bool) {
totalDistributed = totalDistributed.add(_amount);
balances[_to] = balances[_to].add(_amount);
emit Distr(_to, _amount);
emit Transfer(address(0), _to, _amount);
return true;
}
/**
* @dev This function distributes the tokens to the investors when an airdrop happens.
*
*/
function startAirdrop(address _participant, uint _amount) internal {
require( _amount > 0 );
require( totalDistributed < totalSupply );
balances[_participant] = balances[_participant].add(_amount);
totalDistributed = totalDistributed.add(_amount);
if (totalDistributed >= totalSupply) {
distributionFinished = true;
}
// Emit events for transfer and Airdrop
emit Airdrop(_participant, _amount, balances[_participant]);
emit Transfer(address(0), _participant, _amount);
}
/**
* @dev This function claims remaining MTF tokens to receiver.
*
*/
function claimMTFTokens(address _participant, uint _amount) public onlyOwner {
startAirdrop(_participant, _amount);
}
/**
* @dev This function distributes MTF tokens to multiple receivers.
*
*/
function distributeAirdropMultipleInvestors(address[] _addresses, uint _amount) public onlyOwner {
for (uint i = 0; i < _addresses.length; i++)
startAirdrop(_addresses[i], _amount);
}
/**
* @dev This function is responsible for updating token rate per ETH
*
*/
function updateTokensPerEth(uint _tokensPerEth) public onlyOwner {
tokensPerEth = _tokensPerEth;
emit TokensPerEthUpdated(_tokensPerEth);
}
/**
* @dev This is a payable function which gets invoked when ETH is
* sent to this Contract.
*
*/
function () external payable {
sendTokens();
}
/**
* @dev This function gets invoked when ETH is
* sent to this Contract and returns the corresponding MTF token to caller.
*
*/
function sendTokens() payable canDistr public {
uint256 tokens = 0;
// minimum contribution
require( msg.value >= MIN_CONTRIBUTION );
require( msg.value > 0 );
// get baseline number of tokens
tokens = tokensPerEth.mul(msg.value) / 1 ether;
address investor = msg.sender;
if (tokens > 0) {
distr(investor, tokens);
}
if (totalDistributed >= totalSupply) {
distributionFinished = true;
}
}
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address _owner) constant public returns (uint256) {
return balances[_owner];
}
// mitigates the ERC20 short address attack
modifier onlyPayloadSize(uint size) {
assert(msg.data.length >= size + 4);
_;
}
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
function transfer(address _to, uint256 _amount) onlyPayloadSize(2 * 32) public returns (bool success) {
require(_to != address(0));
require(_amount <= balances[msg.sender]);
uint256 _tokenToBurn=calculateBurnAmount(_amount);
uint256 _tokensToTransfer = _amount.sub(_tokenToBurn);
balances[msg.sender] = balances[msg.sender].sub(_amount);
balances[_to] = balances[_to].add(_tokensToTransfer);
totalSupply = totalSupply.sub(_tokenToBurn);
emit Transfer(msg.sender, _to, _tokensToTransfer);
emit Transfer(msg.sender, address(0), _tokenToBurn);
return true;
}
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address _from, address _to, uint256 _amount) onlyPayloadSize(3 * 32) public returns (bool success) {
require(_to != address(0));
require(_amount <= balances[_from]);
require(_amount <= allowed[_from][msg.sender]);
balances[_from] = balances[_from].sub(_amount);
uint256 _tokenToBurn=calculateBurnAmount(_amount);
uint256 _tokensToTransfer = _amount.sub(_tokenToBurn);
balances[_to] = balances[_to].add(_tokensToTransfer);
totalSupply = totalSupply.sub(_tokenToBurn);
allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_amount);
emit Transfer(_from, _to, _tokensToTransfer);
emit Transfer(_from, address(0), _tokenToBurn);
return true;
}
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address _spender, uint256 _value) public returns (bool success) {
// mitigates the ERC20 spend/approval race condition
if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address _owner, address _spender) constant public returns (uint256) {
return allowed[_owner][_spender];
}
/**
* @dev Returns the token balance of the address WHO for this contract.
*
*/
function getTokenBalance(address tokenAddress, address who) constant public returns (uint){
ClaimableToken t = ClaimableToken(tokenAddress);
uint bal = t.balanceOf(who);
return bal;
}
/**
* @dev This function withdraws ETH from the contract.
*
*/
function withdraw() onlyOwner public {
address myAddress = this;
uint256 etherBalance = myAddress.balance;
owner.transfer(etherBalance);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function burn(uint256 _value) onlyOwner public {
require(_value <= balances[msg.sender]);
// no need to require value <= totalSupply, since that would imply the
// sender's balance is greater than the totalSupply, which *should* be an assertion failure
address burner = msg.sender;
balances[burner] = balances[burner].sub(_value);
totalSupply = totalSupply.sub(_value);
totalDistributed = totalDistributed.sub(_value);
emit Burn(burner, _value);
}
/**
* @dev This function withdraws MTF token from the contract.
*
*/
function withdrawMTFTokens(address _tokenContract) onlyOwner public returns (bool) {
ClaimableToken token = ClaimableToken(_tokenContract);
uint256 amount = token.balanceOf(address(this));
return token.transfer(owner, amount);
}
/**
* This function calculates the burn amount to be deducted & burnt on each transfer.
*
**/
function calculateBurnAmount(uint256 amount) internal view returns (uint256) {
uint256 _burnAmount = 0;
// burn amount calculations
if (totalSupply > minimumSupply) {
_burnAmount = (amount.mul(burnRate)).div(1000);//Minimum burn is 0
uint256 availableBurn = totalSupply.sub(minimumSupply);
if (_burnAmount > availableBurn) { //Only half of the total supply can be burnt
_burnAmount = availableBurn;
}
}
return _burnAmount;
}
/**
* @dev Increases/decreases the burn rate
*
* Emits a {TokenBurnRateUpdated} event which sets the transfer rate.
*
*
*/
function updateTokenBurnRate(uint _tokensBurnRate) public onlyOwner {
burnRate = _tokensBurnRate;
emit TokenBurnRateUpdated(_tokensBurnRate);
}
}
{
"compilationTarget": {
"MTFinance.sol": "MTFinance"
},
"evmVersion": "byzantium",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenContract","type":"address"}],"name":"withdrawMTFTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_addresses","type":"address[]"},{"name":"_amount","type":"uint256"}],"name":"distributeAirdropMultipleInvestors","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_participant","type":"address"},{"name":"_amount","type":"uint256"}],"name":"claimMTFTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MIN_CONTRIBUTION","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokensBurnRate","type":"uint256"}],"name":"updateTokenBurnRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"finishDistribution","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokensPerEth","type":"uint256"}],"name":"updateTokensPerEth","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"distributionFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenAddress","type":"address"},{"name":"who","type":"address"}],"name":"getTokenBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokensPerEth","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"sendTokens","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"totalDistributed","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"burnRate","type":"uint256"}],"name":"TokenBurnRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_spender","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Distr","type":"event"},{"anonymous":false,"inputs":[],"name":"DistrFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_balance","type":"uint256"}],"name":"Airdrop","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_tokensPerEth","type":"uint256"}],"name":"TokensPerEthUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"burner","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Burn","type":"event"}]