ETH Price: $3,337.74 (+0.27%)

Contract Diff Checker

Contract Name:
BitburnDistrib

Contract Source Code:

File 1 of 1 : BitburnDistrib

pragma solidity ^0.5.11;

library SafeMath {
	function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
		c = a + b;
		require(c >= a);
	}
	function sub(uint256 a, uint256 b) internal pure returns (uint256 c) {
		require(b <= a);
		c = a - b;
	}
	function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
		c = a * b;
		require(a == 0 || c / a == b);
	}
	function div(uint256 a, uint256 b) internal pure returns (uint256 c) {
		require(b > 0);
		c = a / b;
	}
}

contract Ownable {
	address private _owner;

	event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

	constructor () internal {
		_owner = msg.sender;
		emit OwnershipTransferred(address(0), _owner);
	}

	modifier onlyOwner() {
		require(msg.sender == _owner, "Ownable: caller is not the owner");
		_;
	}

	function owner() public view returns (address) {
		return _owner;
	}

	function transferOwnership(address newOwner) public onlyOwner {
		require(newOwner != address(0), "Ownable: owner cannot be the zero address");
		require(newOwner != address(this), "Ownable: owner cannot be the contract address");
		emit OwnershipTransferred(_owner, newOwner);
		_owner = newOwner;
	}
}

contract Bitburn is Ownable {
	using SafeMath for uint256;

	string constant public name = "Bitburn";
	string constant public symbol = "BTU";
	uint8 constant public decimals = 0;
	uint256 private _totalSupply;
	mapping (address => uint256) private _balances;
	mapping (address => mapping (address => uint256)) private _allowances;

	uint256 private burnRate;

	event Approval(address indexed owner, address indexed spender, uint256 amount);
	event Transfer(address indexed sender, address indexed recipient, uint256 amount);
	event Burn(uint256 amount);
	event BurnRateChanged(uint256 previousBurnRate, uint256 newBurnRate);
	event BurnOwnerTokens(uint256 amount);

	constructor (address _distrib, address _owner) public {
		require(_distrib != address(0) && _owner != address(0));

		transferOwnership(_owner);

		_totalSupply = 2000000;
		_balances[_owner] = _totalSupply*3/10;
		_balances[_distrib] = _totalSupply-_balances[_owner];
		emit Transfer(address(0), _distrib, _balances[_distrib]);
		emit Transfer(address(0), _owner, _balances[_owner]);

		burnRate = 20;
		emit BurnRateChanged(0, burnRate);
	}

	/**
	 * @dev returns the burn percentage of transfer amount.
	 *
	 * Note: see also {setBurnRate}.
	 */
	function getBurnRate() public view returns (uint256) {
		return burnRate;
	}

	/**
	 * @dev sets the burn percentage of transfer amount from 0.5% to 5% inclusive.
	 *
	 * Emits a {BurnRateChanged} event.
	 *
	 * Requirement: `_burnRate` must be within [5; 50] (to programmatically escape using fractional numbers).
	 */
	function setBurnRate(uint256 _burnRate) public onlyOwner {
		//Amount multiplier: [0.005; 0.05]
		require(_burnRate >= 5 && _burnRate <= 50, "Burn rate out of bounds");

		emit BurnRateChanged(burnRate, _burnRate);
		burnRate = _burnRate;
	}

	/**
	 * @dev totally burns the whole `_amount` of the contract's owner.
	 *
	 * Emits a {BurnOwnerTokens} event.
	 *
	 * Requirement: the contract's owner must have a balance of at least `_amount`.
	 */
	function burnOwnerTokens(uint256 _amount) public onlyOwner {
		require(_balances[msg.sender] >= _amount, "Burn amount exceeds balance");

		_balances[msg.sender] = _balances[msg.sender].sub(_amount);
		_totalSupply = _totalSupply.sub(_amount);
		emit BurnOwnerTokens(_amount);
	}

	function totalSupply() public view returns (uint256) {
		return _totalSupply;
	}

	function balanceOf(address _owner) public view returns (uint256) {
		return _balances[_owner];
	}

	function transfer(address _recipient, uint256 _amount) public returns (bool) {
		_transfer(msg.sender, _recipient, _amount);
		return true;
	}

	function transferFrom(address _sender, address _recipient, uint256 _amount) public returns (bool) {
		require(_allowances[_sender][_recipient] >= _amount, "Transfer amount exceeds allowance");

		_transfer(_sender, _recipient, _amount);
		_allowances[_sender][_recipient] = _allowances[_sender][_recipient].sub(_amount);
		return true;
	}

	function _transfer(address _sender, address _recipient, uint256 _amount) internal {
		require(_balances[_sender] >= _amount, "Transfer amount exceeds balance");
		require(_recipient != address(0), "Cannot transfer to the zero address");
		require(_recipient != address(this), "Cannot transfer to the contract address");

		uint256 burnAmount = _amount.mul(burnRate).div(1000);
		uint256 newAmount = _amount.sub(burnAmount);
		_balances[_sender] = _balances[_sender].sub(_amount);
		_balances[_recipient] = _balances[_recipient].add(newAmount);
		_totalSupply = _totalSupply.sub(burnAmount);
		emit Transfer(_sender, _recipient, _amount);
		emit Burn(burnAmount);
	}

	function approve(address _spender, uint256 _amount) public returns (bool) {
		_approve(msg.sender, _spender, _amount);
		return true;
	}

	function allowance(address _owner, address _spender) public view returns (uint256) {
		return _allowances[_owner][_spender];
	}

	function increaseAllowance(address _spender, uint256 _addedValue) public returns (bool) {
		_approve(msg.sender, _spender, _allowances[msg.sender][_spender].add(_addedValue));
		return true;
	}

	function decreaseAllowance(address _spender, uint256 _subtractedValue) public returns (bool) {
		_approve(msg.sender, _spender, _allowances[msg.sender][_spender].sub(_subtractedValue));
		return true;
	}

	function _approve(address _owner, address _spender, uint256 _amount) internal {
		require(_spender != address(0), "Cannot approve to the zero address");
		require(_spender != address(this), "Cannot approve to the contract address");

		_allowances[_owner][_spender] = _amount;
		emit Approval(_owner, _spender, _amount);
	}
}

contract BitburnDistrib is Ownable {
	using SafeMath for uint256;

	Bitburn private BTU;

	bool public SALE_FINALIZED;
	bool private SALE_ACTIVE;
	bool private SELFDROP_ACTIVE;

	uint256 private SALE_PRICE;
	uint256 private SELFDROP_VALUE;
	uint256 private RECIP_ADDIT_TEST;

	uint256 public SALE_TOTALSENT;
	uint256 public SALE_TOTALRECEIVED;
	uint256 public AIRDROP_TOTALSENT;
	uint256 public AIRDROP_TOTALRECEIVED;
	uint256 public SELFDROP_TOTALSENT;
	uint256 public SELFDROP_TOTALRECEIVED;
	uint256 public PARTNERSHIP_TOTALSENT;
	uint256 public PARTNERSHIP_TOTALRECEIVED;

	mapping (address => bool) private AIRDROP_ALLRECIPS;
	mapping (address => bool) private SELFDROP_ALLRECIPS;

	event SaleParamsChanged(bool previous_SALE_ACTIVE, uint256 previous_SALE_PRICE, bool new_SALE_ACTIVE, uint256 new_SALE_PRICE);
	event SelfdropParamsChanged(bool previous_SELFDROP_ACTIVE, uint256 previous_SELFDROP_VALUE, bool new_SELFDROP_ACTIVE, uint256 new_SELFDROP_VALUE);
	event Sold(uint256 sentETH, uint256 boughtETH, uint256 refundedETH, uint256 sentTokens, uint256 receivedTokens);
	event Airdropped(uint256 sentTokens, uint256 receivedTokens);
	event Selfdropped(uint256 sentTokens, uint256 receivedTokens);
	event SentToPartner(address partner, uint256 sentTokens, uint256 receivedTokens);

	constructor () public {
		BTU = new Bitburn(address(this), msg.sender);

		RECIP_ADDIT_TEST = 10000000000000000;
	}

	function getBurnAmount(uint256 _senderAmount) internal view returns (uint256) {
		return _senderAmount.mul(BTU.getBurnRate()).div(1000);
	}

	function getSenderAmount(uint256 _recipientAmount) internal view returns (uint256) {
		return (uint256(1000)).mul(_recipientAmount).div( (uint256(1000)).sub(BTU.getBurnRate()) );
	}

	function getSaleParams() public view returns (bool, uint256) {
		return (SALE_ACTIVE, SALE_PRICE);
	}

	function setSaleParams(bool _SALE_ACTIVE, uint256 _SALE_PRICE) public onlyOwner {
		require(!SALE_FINALIZED, "Changing parameters: token sale already finished");
		require(_SALE_PRICE > 0, "Changing parameters: _SALE_PRICE must be > 0");

		emit SaleParamsChanged(SALE_ACTIVE, SALE_PRICE, _SALE_ACTIVE, _SALE_PRICE);
		SALE_ACTIVE = _SALE_ACTIVE;
		SALE_PRICE = _SALE_PRICE;
	}

	function getSelfdropParams() public view returns (bool, uint256) {
		return (SELFDROP_ACTIVE, SELFDROP_VALUE);
	}

	function setSelfdropParams(bool _SELFDROP_ACTIVE, uint256 _SELFDROP_VALUE) public onlyOwner {
		require(_SELFDROP_VALUE > 0, "Changing parameters: _SELFDROP_VALUE must be > 0");

		emit SelfdropParamsChanged(SELFDROP_ACTIVE, SELFDROP_VALUE, _SELFDROP_ACTIVE, _SELFDROP_VALUE);
		SELFDROP_ACTIVE = _SELFDROP_ACTIVE;
		SELFDROP_VALUE = _SELFDROP_VALUE;
	}

	function getRecipAdditTest() public view returns (uint256) {
		return RECIP_ADDIT_TEST;
	}

	function setRecipAdditTest(uint256 _RECIP_ADDIT_TEST) public onlyOwner {
		RECIP_ADDIT_TEST = _RECIP_ADDIT_TEST;
	}

	function() external payable {
		if (msg.data.length == 0) {
			if (msg.value >= SALE_PRICE) {
				if (SALE_ACTIVE) {
					uint256 thisTokenBalance = BTU.balanceOf(address(this));
					require(thisTokenBalance > 0, "Token sale: the contract address has no tokens");

					uint256 nettoTake = msg.value.div(SALE_PRICE);
					uint256 bruttoTake = getSenderAmount(nettoTake);

					if (bruttoTake > thisTokenBalance) {
						uint256 nettoGive = thisTokenBalance.sub(getBurnAmount(thisTokenBalance));
						uint256 totalCost = nettoGive.mul(SALE_PRICE);
						uint256 r = msg.value.sub(totalCost);
						if (r > 0) {
							msg.sender.transfer(r);
						}
						require(BTU.transfer(msg.sender, thisTokenBalance));
						SALE_TOTALSENT = SALE_TOTALSENT.add(thisTokenBalance);
						SALE_TOTALRECEIVED = SALE_TOTALRECEIVED.add(nettoGive);
						emit Sold(msg.value, totalCost, r, thisTokenBalance, nettoGive);
					}
					else {
						uint256 totalCost = nettoTake.mul(SALE_PRICE);
						uint256 r = msg.value.sub(totalCost);
						if (r > 0) {
							msg.sender.transfer(r);
						}
						require(BTU.transfer(msg.sender, bruttoTake));
						SALE_TOTALSENT = SALE_TOTALSENT.add(bruttoTake);
						SALE_TOTALRECEIVED = SALE_TOTALRECEIVED.add(nettoTake);
						emit Sold(msg.value, totalCost, r, bruttoTake, nettoTake);
					}
				}
				else if (SALE_FINALIZED) {
					revert("Token sale: already finished");
				}
				else {
					revert("Token sale: currently inactive");
				}
			}
			else if (msg.value == 0) {
				if (SELFDROP_ACTIVE) {
					require(!SELFDROP_ALLRECIPS[msg.sender] && msg.sender.balance >= RECIP_ADDIT_TEST, "Token selfdrop: recipient not validated");
					uint256 thisTokenBalance = BTU.balanceOf(address(this));
					require(thisTokenBalance > 0, "Token selfdrop: the contract address has no tokens");

					SELFDROP_ALLRECIPS[msg.sender] = true;
					uint256 bruttoGive = getSenderAmount(SELFDROP_VALUE);

					if (thisTokenBalance >= bruttoGive) {
						require(BTU.transfer(msg.sender, bruttoGive));
						SELFDROP_TOTALSENT = SELFDROP_TOTALSENT.add(bruttoGive);
						SELFDROP_TOTALRECEIVED = SELFDROP_TOTALRECEIVED.add(SELFDROP_VALUE);
						emit Selfdropped(bruttoGive, SELFDROP_VALUE);
					}
					else {
						uint256 nettoGive = thisTokenBalance.sub(getBurnAmount(thisTokenBalance));
						require(BTU.transfer(msg.sender, thisTokenBalance));
						SELFDROP_TOTALSENT = SELFDROP_TOTALSENT.add(thisTokenBalance);
						SELFDROP_TOTALRECEIVED = SELFDROP_TOTALRECEIVED.add(nettoGive);
						emit Selfdropped(thisTokenBalance, nettoGive);
					}
				}
				else {
					revert("Token selfdrop: currently inactive");
				}
			}
			else {
				revert("Token sale / selfdrop: invalid query");
			}
		}
	}

	function airdropTokens(address[] memory _batchRecips, uint256 _value) public onlyOwner {
		uint256 recipsLength = _batchRecips.length;
		uint256 bruttoGive = getSenderAmount(_value);
		require(BTU.balanceOf(address(this)) >= recipsLength*bruttoGive, "Token airdrop: the contract address has not enough tokens");

		uint256 BATCHSENT;
		uint256 BATCHRECEIVED;
		for (uint256 i=0; i<recipsLength; i++) {
			if (!AIRDROP_ALLRECIPS[_batchRecips[i]]) {
				AIRDROP_ALLRECIPS[_batchRecips[i]] = true;
				require(BTU.transfer(_batchRecips[i], bruttoGive));
				BATCHSENT = BATCHSENT.add(bruttoGive);
				BATCHRECEIVED = BATCHRECEIVED.add(_value);
			}
		}
		AIRDROP_TOTALSENT = AIRDROP_TOTALSENT.add(BATCHSENT);
		AIRDROP_TOTALRECEIVED = AIRDROP_TOTALRECEIVED.add(BATCHRECEIVED);
		emit Airdropped(BATCHSENT, BATCHRECEIVED);
	}

	function SendToPartner(address _partner, uint256 _amount) public onlyOwner {
		uint256 bruttoGive = getSenderAmount(_amount);
		require(BTU.transfer(_partner, bruttoGive));
		PARTNERSHIP_TOTALSENT = PARTNERSHIP_TOTALSENT.add(bruttoGive);
		PARTNERSHIP_TOTALRECEIVED = PARTNERSHIP_TOTALRECEIVED.add(_amount);
		emit SentToPartner(_partner, bruttoGive, _amount);
	}

	function withdrawTokens(uint256 _amount) public onlyOwner {
		require(!(SELFDROP_ACTIVE || SALE_ACTIVE), "Token withdrawal: cannot withdraw funds while token distribution is active");

		require(BTU.transfer(msg.sender, _amount));
	}

	function withdrawEth(uint256 _amount) public onlyOwner {
		require(!(SELFDROP_ACTIVE || SALE_ACTIVE), "ETH withdrawal: cannot withdraw funds while token distribution is active");

		msg.sender.transfer(_amount);
	}

	function finalizeSale() public onlyOwner {
		require(!(SELFDROP_ACTIVE || SALE_ACTIVE) && BTU.balanceOf(address(this)) == 0, "Finalizing token sale: requirements not met");

		SALE_FINALIZED = true;
	}
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):