ETH Price: $3,337.93 (-1.17%)
Gas: 6.46 Gwei

Contract

0xF19Ed2025eFfdb2b22d1376c09b4884F26475DD1
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve196513722024-04-14 4:23:47253 days ago1713068627IN
Karma Finance: KFI Token
0 ETH0.0002782211.40404298
Approve161181922022-12-05 11:05:23748 days ago1670238323IN
Karma Finance: KFI Token
0 ETH0.000628813.47014899
Approve156970492022-10-07 15:15:23807 days ago1665155723IN
Karma Finance: KFI Token
0 ETH0.0009692420.76309772
Approve151507422022-07-16 1:26:20891 days ago1657934780IN
Karma Finance: KFI Token
0 ETH0.000190727.81740747
Approve124550122021-05-17 23:57:231315 days ago1621295843IN
Karma Finance: KFI Token
0 ETH0.0010657273
Approve123042932021-04-24 17:33:191338 days ago1619285599IN
Karma Finance: KFI Token
0 ETH0.0028008660
Approve120891822021-03-22 14:35:001371 days ago1616423700IN
Karma Finance: KFI Token
0 ETH0.00930657210
Transfer119721542021-03-04 13:48:411389 days ago1614865721IN
Karma Finance: KFI Token
0 ETH0.00401973110
Transfer116533822021-01-14 13:05:461438 days ago1610629546IN
Karma Finance: KFI Token
0 ETH0.0023745165
Approve116377542021-01-12 3:36:001441 days ago1610422560IN
Karma Finance: KFI Token
0 ETH0.0024965356
Approve114733172020-12-17 22:22:061466 days ago1608243726IN
Karma Finance: KFI Token
0 ETH0.0038250485.8
Approve114632202020-12-16 9:10:011468 days ago1608109801IN
Karma Finance: KFI Token
0 ETH0.0023182152
Approve114466572020-12-13 19:50:461470 days ago1607889046IN
Karma Finance: KFI Token
0 ETH0.0022290550
Approve114306702020-12-11 9:03:581473 days ago1607677438IN
Karma Finance: KFI Token
0 ETH0.0022290550.00000145
Approve114049132020-12-07 9:35:231477 days ago1607333723IN
Karma Finance: KFI Token
0 ETH0.0016049136
Transfer113087462020-11-22 15:11:311491 days ago1606057891IN
Karma Finance: KFI Token
0 ETH0.001010248
Transfer113087342020-11-22 15:09:501491 days ago1606057790IN
Karma Finance: KFI Token
0 ETH0.00100848
Approve112221222020-11-09 8:09:571505 days ago1604909397IN
Karma Finance: KFI Token
0 ETH0.0014624633
Approve111950602020-11-05 4:30:381509 days ago1604550638IN
Karma Finance: KFI Token
0 ETH0.0009406521.1
Approve111868662020-11-03 22:20:431510 days ago1604442043IN
Karma Finance: KFI Token
0 ETH0.0009306521
Transfer111677942020-10-31 23:56:131513 days ago1604188573IN
Karma Finance: KFI Token
0 ETH0.0009273418
Approve111643122020-10-31 11:16:441513 days ago1604143004IN
Karma Finance: KFI Token
0 ETH0.001159126
Approve111618482020-10-31 2:09:341514 days ago1604110174IN
Karma Finance: KFI Token
0 ETH0.0012928429
Transfer111558812020-10-30 4:01:131515 days ago1604030473IN
Karma Finance: KFI Token
0 ETH0.0039678877
Transfer111558732020-10-30 3:59:251515 days ago1604030365IN
Karma Finance: KFI Token
0 ETH0.0039669677
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ExternalTokenTemplate

Compiler Version
v0.5.0+commit.1d4f565a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-09-04
*/

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see `ERC20Detailed`.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view 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 recipient, uint256 amount) external returns (bool);

    /**
     * @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) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * > 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 amount) external returns (bool);

    /**
     * @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 sender, address recipient, uint256 amount) external 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);

    /**
     * @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);
}

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.5.0;

/**
 * @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 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) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @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) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @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) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        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) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. 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 mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol

pragma solidity ^0.5.0;



/**
 * @dev Implementation of the `IERC20` interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using `_mint`.
 * For a generic mechanism see `ERC20Mintable`.
 *
 * *For a detailed writeup see our guide [How to implement supply
 * mechanisms](https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226).*
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an `Approval` event is emitted on calls to `transferFrom`.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard `decreaseAllowance` and `increaseAllowance`
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See `IERC20.approve`.
 */
contract ERC20 is IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    /**
     * @dev See `IERC20.totalSupply`.
     */
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See `IERC20.balanceOf`.
     */
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See `IERC20.transfer`.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public returns (bool) {
        _transfer(msg.sender, recipient, amount);
        return true;
    }

    /**
     * @dev See `IERC20.allowance`.
     */
    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See `IERC20.approve`.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 value) public returns (bool) {
        _approve(msg.sender, spender, value);
        return true;
    }

    /**
     * @dev See `IERC20.transferFrom`.
     *
     * Emits an `Approval` event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of `ERC20`;
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `value`.
     * - the caller must have allowance for `sender`'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to `approve` that can be used as a mitigation for
     * problems described in `IERC20.approve`.
     *
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to `approve` that can be used as a mitigation for
     * problems described in `IERC20.approve`.
     *
     * Emits an `Approval` event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
        _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to `transfer`, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a `Transfer` event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _balances[sender] = _balances[sender].sub(amount);
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a `Transfer` event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

     /**
     * @dev Destoys `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(address account, uint256 value) internal {
        require(account != address(0), "ERC20: burn from the zero address");

        _totalSupply = _totalSupply.sub(value);
        _balances[account] = _balances[account].sub(value);
        emit Transfer(account, address(0), value);
    }

    /**
     * @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 owner, address spender, uint256 value) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = value;
        emit Approval(owner, spender, value);
    }

    /**
     * @dev Destoys `amount` tokens from `account`.`amount` is then deducted
     * from the caller's allowance.
     *
     * See `_burn` and `_approve`.
     */
    function _burnFrom(address account, uint256 amount) internal {
        _burn(account, amount);
        _approve(account, msg.sender, _allowances[account][msg.sender].sub(amount));
    }
}

// File: @openzeppelin/contracts/ownership/Ownable.sol

pragma solidity ^0.5.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be aplied to your functions to restrict their use to
 * the owner.
 */
contract Ownable {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * > Note: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: contracts/TownToken.sol

pragma solidity ^0.5.0;



interface TownInterface {
    function checkProposal(address proposal) external returns (bool);
    function voteOn(address externalToken, uint256 amount) external returns (bool);
}


contract TownToken is ERC20, Ownable {
    using SafeMath for uint256;

    string public constant name = "Town Token";
    string public constant symbol = "TTW";
    uint8 public constant decimals = 18;

    bool public initiated;

    address[] private _holders;

    TownInterface _town;

    constructor () public {
        initiated = false;
    }

    function getHoldersCount() external view returns (uint256) {
        return _holders.length;
    }

    function getHolderByIndex(uint256 index) external view returns (address) {
        return _holders[index];
    }

    function init (uint256 totalSupply, address townContract) public onlyOwner {
        require(initiated == false, "contract already initiated");
        _town = TownInterface(townContract);
        _mint(townContract, totalSupply);
        initiated = true;
    }

    function transfer(address recipient, uint256 amount) public returns (bool) {
        if (msg.sender != address(_town)) {
            if (_town.checkProposal(recipient) == true) {
                super.transfer(address(_town), amount);
                return _town.voteOn(recipient, amount);
            }
            // check 223 ERC and call voteOn function
        }

        if (recipient != address(_town)) {
            bool found = false;
            for (uint i = 0; i < _holders.length; ++i) {    // find recipient address in holders list
                if (_holders[i] == recipient) {
                    found = true;
                    break;
                }
            }
            if (found == false) {                           // if recipient not found, we push new address
                _holders.push(recipient);
            }
        }

        if (balanceOf(address(msg.sender)) == amount && msg.sender != address(_town)) { // remove address with 0 balance from holders
            uint i = 0;
            for (; i < _holders.length; ++i) {
                if (_holders[i] == address(msg.sender)) {
                    break;
                }
            }

            if (i < (_holders.length - 1)) {
                _holders[i] = _holders[_holders.length - 1];
                delete _holders[_holders.length - 1];
                _holders.length--;
            }
        }

        return super.transfer(recipient, amount);
    }
}

// File: contracts/ExternalTokenTemplate.sol

pragma solidity ^0.5.0;



contract ExternalTokenTemplate is ERC20 {
    using SafeMath for uint256;

    string public constant name = "Karma Finance";
    string public constant symbol = "KFI";
    uint8 public constant decimals = 18;

    constructor (uint256 totalSupply) public {
        _mint(msg.sender, totalSupply);
    }
}

// File: contracts/Town.sol

pragma solidity ^0.5.0;




contract Town is TownInterface {
    using SafeMath for uint256;

    uint256 private _distributionPeriod;
    uint256 private _distributionPeriodsNumber;
    uint256 private _startRate;
    uint256 private _minTokenGetAmount;
    uint256 private _durationOfMinTokenGetAmount;
    uint256 private _maxTokenGetAmount;
    uint256 private _minExternalTokensAmount;
    uint256 private _minSignAmount;
    uint256 private _lastDistributionsDate;

    uint256 private _transactionsCount;

    struct ExternalTokenDistributionsInfo {
        address _official;
        uint256 _distributionAmount;
        uint256 _distributionsCount;
    }

    struct ExternalToken {
        ExternalTokenDistributionsInfo[] _entities;
        uint256 _weight;
    }

    struct TransactionsInfo {
        uint256 _rate;
        uint256 _amount;
    }

    struct TownTokenRequest {
        address _address;
        TransactionsInfo _info;
    }

    struct RemunerationsInfo {
        address payable _address;
        uint256 _priority;
        uint256 _amount;
    }

    struct RemunerationsOfficialsInfo {
        uint256 _amount;
        uint256 _decayTimestamp;
    }

    TownToken private _token;

    mapping (address => TransactionsInfo[]) private _historyTransactions;

    TownTokenRequest[] private _queueTownTokenRequests;

    RemunerationsInfo[] private _remunerationsQueue;

    mapping (address => ExternalToken) private _externalTokens;
    address[] private _externalTokensAddresses;

    mapping (address => mapping (address => uint256)) private _townHoldersLedger;
    mapping (address => address[]) private _ledgerExternalTokensAddresses;

    mapping (address => RemunerationsOfficialsInfo) private _officialsLedger;

    address[] private _externalTokensWithWight;

    modifier onlyTownTokenSmartContract {
        require(msg.sender == address(_token), "only town token smart contract can call this function");
        _;
    }

    constructor (
        uint256 distributionPeriod,
        uint256 distributionPeriodsNumber,
        uint256 startRate,
        uint256 minTokenGetAmount,
        uint256 durationOfMinTokenGetAmount,
        uint256 maxTokenGetAmount,
        uint256 minExternalTokensAmount,
        address tokenAddress) public {
        require(distributionPeriod > 0, "distributionPeriod wrong");
        require(distributionPeriodsNumber > 0, "distributionPeriodsNumber wrong");
        require(minTokenGetAmount > 0, "minTokenGetAmount wrong");
        require(durationOfMinTokenGetAmount > 0, "durationOfMinTokenGetAmount wrong");
        require(maxTokenGetAmount > 0, "maxTokenGetAmount wrong");
        require(minExternalTokensAmount > 0, "minExternalTokensAmount wrong");

        _distributionPeriod = distributionPeriod * 1 days;
        _distributionPeriodsNumber = distributionPeriodsNumber;
        _startRate = startRate;

        _token = TownToken(tokenAddress);

        _transactionsCount = 0;
        _minTokenGetAmount = minTokenGetAmount;
        _durationOfMinTokenGetAmount = durationOfMinTokenGetAmount;
        _maxTokenGetAmount = maxTokenGetAmount;
        _minExternalTokensAmount = minExternalTokensAmount;
        _lastDistributionsDate = (now.div(86400).add(1)).mul(86400);
        _minSignAmount = 10000000000000;
    }

    function () external payable {
        if (msg.value <= _minSignAmount) {
            if (_officialsLedger[msg.sender]._amount > 0) {
                claimFunds(msg.sender);
            }
            if (_ledgerExternalTokensAddresses[msg.sender].length > 0) {
                claimExternalTokens(msg.sender);
            }
            return;
        }
        uint256 tokenAmount = IWantTakeTokensToAmount(msg.value);
        require(_transactionsCount > _durationOfMinTokenGetAmount || tokenAmount > _minTokenGetAmount, "insufficient amount");

        getTownTokens(msg.sender);
    }

    function token() external view returns (IERC20) {
        return _token;
    }

    function distributionPeriod() external view returns (uint256) {
        return _distributionPeriod;
    }

    function distributionPeriodsNumber() external view returns (uint256) {
        return _distributionPeriodsNumber;
    }

    function startRate() external view returns (uint256) {
        return _startRate;
    }

    function minTokenGetAmount() external view returns (uint256) {
        return _minTokenGetAmount;
    }

    function durationOfMinTokenGetAmount() external view returns (uint256) {
        return _durationOfMinTokenGetAmount;
    }

    function maxTokenGetAmount() external view returns (uint256) {
        return _maxTokenGetAmount;
    }

    function minExternalTokensAmount() external view returns (uint256) {
        return _minExternalTokensAmount;
    }

    function lastDistributionsDate() external view returns (uint256) {
        return _lastDistributionsDate;
    }

    function transactionsCount() external view returns (uint256) {
        return _transactionsCount;
    }

    function getCurrentRate() external view returns (uint256) {
        return currentRate();
    }

    function getLengthRemunerationQueue() external view returns (uint256) {
        return _remunerationsQueue.length;
    }

    function getMinSignAmount() external view returns (uint256) {
        return _minSignAmount;
    }

    function getRemunerationQueue(uint256 index) external view returns (address, uint256, uint256) {
        return (_remunerationsQueue[index]._address, _remunerationsQueue[index]._priority, _remunerationsQueue[index]._amount);
    }

    function getLengthQueueTownTokenRequests() external view returns (uint256) {
        return _queueTownTokenRequests.length;
    }

    function getQueueTownTokenRequests(uint256 index) external  view returns (address, uint256, uint256) {
        TownTokenRequest memory tokenRequest = _queueTownTokenRequests[index];
        return (tokenRequest._address, tokenRequest._info._rate, tokenRequest._info._amount);
    }

    function getMyTownTokens() external view returns (uint256, uint256) {
        uint256 amount = 0;
        uint256 tokenAmount = 0;
        for (uint256 i = 0; i < _historyTransactions[msg.sender].length; ++i) {
            amount = amount.add(_historyTransactions[msg.sender][i]._amount.mul(_historyTransactions[msg.sender][i]._rate).div(10 ** 18));
            tokenAmount = tokenAmount.add(_historyTransactions[msg.sender][i]._amount);
        }
        return (amount, tokenAmount);
    }

    function checkProposal(address proposal) external returns (bool) {
        if (_externalTokens[proposal]._entities.length > 0) {
            return true;
        }
        return false;
    }

    function sendExternalTokens(address official, address externalToken) external returns (bool) {
        ERC20 tokenERC20 = ERC20(externalToken);
        uint256 balance = tokenERC20.allowance(official, address(this));
        require(tokenERC20.balanceOf(official) >= balance, "Official should have external tokens for approved");
        require(balance > 0, "External tokens must be approved for town smart contract");
        tokenERC20.transferFrom(official, address(this), balance);

        ExternalTokenDistributionsInfo memory tokenInfo;
        tokenInfo._official = official;
        tokenInfo._distributionsCount = _distributionPeriodsNumber;
        tokenInfo._distributionAmount = balance.div(_distributionPeriodsNumber);

        ExternalToken storage tokenObj = _externalTokens[externalToken];

        if (tokenObj._entities.length == 0) {
            _externalTokensAddresses.push(externalToken);
        }

        tokenObj._entities.push(tokenInfo);

        return true;
    }

    function remuneration(uint256 tokensAmount) external returns (bool) {
        require(_token.balanceOf(msg.sender) >= tokensAmount, "Town tokens not found");
        require(_token.allowance(msg.sender, address(this)) >= tokensAmount, "Town tokens must be approved for town smart contract");

        uint256 debt = 0;
        uint256 restOfTokens = tokensAmount;
        uint256 executedRequestCount = 0;
        for (uint256 i = 0; i < _queueTownTokenRequests.length; ++i) {
            address user = _queueTownTokenRequests[i]._address;
            uint256 rate = _queueTownTokenRequests[i]._info._rate;
            uint256 amount = _queueTownTokenRequests[i]._info._amount;
            if (restOfTokens > amount) {
                _token.transferFrom(msg.sender, user, amount);
                restOfTokens = restOfTokens.sub(amount);
                debt = debt.add(amount.mul(rate).div(10 ** 18));
                executedRequestCount++;
            } else {
                break;
            }
        }

        if (restOfTokens > 0) {
            _token.transferFrom(msg.sender, address(this), restOfTokens);
        }

        if (executedRequestCount > 0) {
            for (uint256 i = executedRequestCount; i < _queueTownTokenRequests.length; ++i) {
                _queueTownTokenRequests[i - executedRequestCount] = _queueTownTokenRequests[i];
            }

            for (uint256 i = 0; i < executedRequestCount; ++i) {
                delete _queueTownTokenRequests[_queueTownTokenRequests.length - 1];
                _queueTownTokenRequests.length--;
            }
        }

        if (_historyTransactions[msg.sender].length > 0) {
            for (uint256 i = _historyTransactions[msg.sender].length - 1; ; --i) {
                uint256 rate = _historyTransactions[msg.sender][i]._rate;
                uint256 amount = _historyTransactions[msg.sender][i]._amount;
                delete _historyTransactions[msg.sender][i];
                _historyTransactions[msg.sender].length--;

                if (restOfTokens < amount) {
                    TransactionsInfo memory info = TransactionsInfo(rate, amount.sub(restOfTokens));
                    _historyTransactions[msg.sender].push(info);

                    debt = debt.add(restOfTokens.mul(rate).div(10 ** 18));
                    break;
                }

                debt = debt.add(amount.mul(rate).div(10 ** 18));
                restOfTokens = restOfTokens.sub(amount);

                if (i == 0) break;
            }
        }

        if (debt > address(this).balance) {
            msg.sender.transfer(address(this).balance);

            RemunerationsInfo memory info = RemunerationsInfo(msg.sender, 2, debt.sub(address(this).balance));
            _remunerationsQueue.push(info);
        } else {
            msg.sender.transfer(debt);
        }

        return true;
    }

    function distributionSnapshot() external returns (bool) {
        require(now > (_lastDistributionsDate + _distributionPeriod), "distribution time has not yet arrived");

        uint256 sumWeight = 0;
        address[] memory tempArray;
        _externalTokensWithWight = tempArray;
        for (uint256 i = 0; i < _externalTokensAddresses.length; ++i) {
            ExternalToken memory externalToken = _externalTokens[_externalTokensAddresses[i]];
            if (externalToken._weight > 0) {
                uint256 sumExternalTokens = 0;
                for (uint256 j = 0; j < externalToken._entities.length; ++j) {
                    if (externalToken._entities[j]._distributionsCount > 0) {
                        ExternalTokenDistributionsInfo memory info = externalToken._entities[j];
                        sumExternalTokens = sumExternalTokens.add(info._distributionAmount.mul(info._distributionsCount));
                    }
                }
                if (sumExternalTokens > _minExternalTokensAmount) {
                    sumWeight = sumWeight.add(externalToken._weight);
                    _externalTokensWithWight.push(_externalTokensAddresses[i]);
                } else {
                    externalToken._weight = 0;
                }
            }
        }

        uint256 fullBalance = address(this).balance;
        for (uint256 i = 0; i < _externalTokensWithWight.length; ++i) {
            ExternalToken memory externalToken = _externalTokens[_externalTokensWithWight[i]];
            uint256 sumExternalTokens = 0;
            for (uint256 j = 0; j < externalToken._entities.length; ++j) {
                sumExternalTokens = sumExternalTokens.add(externalToken._entities[j]._distributionAmount);
            }
            uint256 externalTokenCost = fullBalance.mul(externalToken._weight).div(sumWeight);
            for (uint256 j = 0; j < externalToken._entities.length; ++j) {
                address official = externalToken._entities[j]._official;
                uint256 tokensAmount = externalToken._entities[j]._distributionAmount;
                uint256 amount = externalTokenCost.mul(tokensAmount).div(sumExternalTokens);
                uint256 decayTimestamp = (now - _lastDistributionsDate).div(_distributionPeriod).mul(_distributionPeriod).add(_lastDistributionsDate).add(_distributionPeriod);
                _officialsLedger[official] = RemunerationsOfficialsInfo(amount, decayTimestamp);
            }
        }

        uint256 sumHoldersTokens = _token.totalSupply().sub(_token.balanceOf(address(this)));

        if (sumHoldersTokens != 0) {
            for (uint256 i = 0; i < _token.getHoldersCount(); ++i) {
                address holder = _token.getHolderByIndex(i);
                uint256 balance = _token.balanceOf(holder);
                for (uint256 j = 0; j < _externalTokensAddresses.length; ++j) {
                    address externalTokenAddress = _externalTokensAddresses[j];
                    ExternalToken memory externalToken = _externalTokens[externalTokenAddress];
                    for (uint256 k = 0; k < externalToken._entities.length; ++k) {
                        if (holder != address(this) && externalToken._entities[k]._distributionsCount > 0) {
                            uint256 percent = balance.mul(externalToken._entities[k]._distributionAmount).div(sumHoldersTokens);
                            if (percent > (10 ** 4)) {
                                address[] memory externalTokensForHolder = _ledgerExternalTokensAddresses[holder];
                                bool found = false;
                                for (uint256 h = 0; h < externalTokensForHolder.length; ++h) {
                                    if (externalTokensForHolder[h] == externalTokenAddress) {
                                        found = true;
                                        break;
                                    }
                                }
                                if (found == false) {
                                    _ledgerExternalTokensAddresses[holder].push(externalTokenAddress);
                                }

                                _townHoldersLedger[holder][externalTokenAddress] = _townHoldersLedger[holder][externalTokenAddress].add(percent);
                            }
                        }
                    }
                }
            }

            for (uint256 j = 0; j < _externalTokensAddresses.length; ++j) {
                ExternalTokenDistributionsInfo[] memory tempEntities = _externalTokens[_externalTokensAddresses[j]]._entities;

                for (uint256 k = 0; k < tempEntities.length; ++k) {
                    delete _externalTokens[_externalTokensAddresses[j]]._entities[k];
                }
                _externalTokens[_externalTokensAddresses[j]]._entities.length = 0;

                for (uint256 k = 0; k < tempEntities.length; ++k) {
                    tempEntities[k]._distributionsCount--;
                    if (tempEntities[k]._distributionsCount > 0) {
                        _externalTokens[_externalTokensAddresses[j]]._entities.push(tempEntities[k]);
                    }
                }
            }
        }

        for (uint256 i = 0; i < _externalTokensAddresses.length; ++i) {
            if (_externalTokens[_externalTokensAddresses[i]]._weight > 0) {
                _externalTokens[_externalTokensAddresses[i]]._weight = 0;
            }
        }

        _lastDistributionsDate = _lastDistributionsDate.add(_distributionPeriod);
        return true;
    }

    function voteOn(address externalToken, uint256 amount) external onlyTownTokenSmartContract returns (bool) {
        require(_externalTokens[externalToken]._entities.length > 0, "external token address not found");
        require(now < (_lastDistributionsDate + _distributionPeriod), "need call distributionSnapshot function");

        _externalTokens[externalToken]._weight = _externalTokens[externalToken]._weight.add(amount);
        return true;
    }

    function claimExternalTokens(address holder) public returns (bool) {
        address[] memory externalTokensForHolder = _ledgerExternalTokensAddresses[holder];
        if (externalTokensForHolder.length > 0) {
            for (uint256 i = externalTokensForHolder.length - 1; ; --i) {
                ERC20(externalTokensForHolder[i]).transfer(holder, _townHoldersLedger[holder][externalTokensForHolder[i]]);
                delete _townHoldersLedger[holder][externalTokensForHolder[i]];
                delete _ledgerExternalTokensAddresses[holder][i];
                _ledgerExternalTokensAddresses[holder].length--;

                if (i == 0) break;
            }
        }

        return true;
    }

    function claimFunds(address payable official) public returns (bool) {
        require(_officialsLedger[official]._amount != 0, "official address not found in ledger");

        if (now >= _officialsLedger[official]._decayTimestamp) {
            RemunerationsOfficialsInfo memory info = RemunerationsOfficialsInfo(0, 0);
            _officialsLedger[official] = info;
            return false;
        }

        uint256 amount = _officialsLedger[official]._amount;
        if (address(this).balance >= amount) {
            official.transfer(amount);
        } else {
            RemunerationsInfo memory info = RemunerationsInfo(official, 1, amount);
            _remunerationsQueue.push(info);
        }
        RemunerationsOfficialsInfo memory info = RemunerationsOfficialsInfo(0, 0);
        _officialsLedger[official] = info;

        return true;
    }

    function IWantTakeTokensToAmount(uint256 amount) public view returns (uint256) {
        return amount.mul(10 ** 18).div(currentRate());
    }

    function getTownTokens(address holder) public payable returns (bool) {
        require(holder != address(0), "holder address cannot be null");

        uint256 amount = msg.value;
        uint256 tokenAmount = IWantTakeTokensToAmount(amount);
        uint256 rate = currentRate();
        if (_transactionsCount < _durationOfMinTokenGetAmount && tokenAmount < _minTokenGetAmount) {
            return false;
        }
        if (tokenAmount >= _maxTokenGetAmount) {
            tokenAmount = _maxTokenGetAmount;
            uint256 change = amount.sub(_maxTokenGetAmount.mul(rate).div(10 ** 18));
            msg.sender.transfer(change);
            amount = amount.sub(change);
        }

        if (_token.balanceOf(address(this)) >= tokenAmount) {
            TransactionsInfo memory transactionsHistory = TransactionsInfo(rate, tokenAmount);
            _token.transfer(holder, tokenAmount);
            _historyTransactions[holder].push(transactionsHistory);
            _transactionsCount = _transactionsCount.add(1);
        } else {
            if (_token.balanceOf(address(this)) > 0) {
                uint256 tokenBalance = _token.balanceOf(address(this));
                _token.transfer(holder, tokenBalance);
                TransactionsInfo memory transactionsHistory = TransactionsInfo(rate, tokenBalance);
                _historyTransactions[holder].push(transactionsHistory);
                tokenAmount = tokenAmount.sub(tokenBalance);
            }

            TransactionsInfo memory transactionsInfo = TransactionsInfo(rate, tokenAmount);
            TownTokenRequest memory tokenRequest = TownTokenRequest(holder, transactionsInfo);
            _queueTownTokenRequests.push(tokenRequest);
        }

        for (uint256 i = 0; i < _remunerationsQueue.length; ++i) {
            if (_remunerationsQueue[i]._priority == 1) {
                if (_remunerationsQueue[i]._amount > amount) {
                    _remunerationsQueue[i]._address.transfer(_remunerationsQueue[i]._amount);
                    amount = amount.sub(_remunerationsQueue[i]._amount);

                    delete _remunerationsQueue[i];
                    for (uint j = i + 1; j < _remunerationsQueue.length; ++j) {
                        _remunerationsQueue[j - 1] = _remunerationsQueue[j];
                    }
                    _remunerationsQueue.length--;
                } else {
                    _remunerationsQueue[i]._address.transfer(amount);
                    _remunerationsQueue[i]._amount = _remunerationsQueue[i]._amount.sub(amount);
                    break;
                }
            }
        }

        for (uint256 i = 0; i < _remunerationsQueue.length; ++i) {
            if (_remunerationsQueue[i]._amount > amount) {
                _remunerationsQueue[i]._address.transfer(_remunerationsQueue[i]._amount);
                amount = amount.sub(_remunerationsQueue[i]._amount);

                delete _remunerationsQueue[i];
                for (uint j = i + 1; j < _remunerationsQueue.length; ++j) {
                    _remunerationsQueue[j - 1] = _remunerationsQueue[j];
                }
                _remunerationsQueue.length--;
            } else {
                _remunerationsQueue[i]._address.transfer(amount);
                _remunerationsQueue[i]._amount = _remunerationsQueue[i]._amount.sub(amount);
                break;
            }
        }

        return true;
    }

    function currentRate() internal view returns (uint256) {
        return _startRate;
    }
}

Contract Security Audit

Contract ABI

[{"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":"","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":"sender","type":"address"},{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","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"},{"inputs":[{"name":"totalSupply","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"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"}]

608060405234801561001057600080fd5b50604051602080610b0e8339810180604052602081101561003057600080fd5b5051610045338264010000000061004b810204565b506101e0565b600160a060020a03821615156100c257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6002546100dc908264010000000061088f61016582021704565b600255600160a060020a03821660009081526020819052604090205461010f908264010000000061088f61016582021704565b600160a060020a0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6000828201838110156101d957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b61091f806101ef6000396000f3fe6080604052600436106100ae5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100b3578063095ea7b31461013d57806318160ddd1461018a57806323b872dd146101b1578063313ce567146101f4578063395093511461021f57806370a082311461025857806395d89b411461028b578063a457c2d7146102a0578063a9059cbb146102d9578063dd62ed3e14610312575b600080fd5b3480156100bf57600080fd5b506100c861034d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101025781810151838201526020016100ea565b50505050905090810190601f16801561012f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014957600080fd5b506101766004803603604081101561016057600080fd5b50600160a060020a038135169060200135610384565b604080519115158252519081900360200190f35b34801561019657600080fd5b5061019f61039a565b60408051918252519081900360200190f35b3480156101bd57600080fd5b50610176600480360360608110156101d457600080fd5b50600160a060020a038135811691602081013590911690604001356103a0565b34801561020057600080fd5b506102096103f7565b6040805160ff9092168252519081900360200190f35b34801561022b57600080fd5b506101766004803603604081101561024257600080fd5b50600160a060020a0381351690602001356103fc565b34801561026457600080fd5b5061019f6004803603602081101561027b57600080fd5b5035600160a060020a0316610438565b34801561029757600080fd5b506100c8610453565b3480156102ac57600080fd5b50610176600480360360408110156102c357600080fd5b50600160a060020a03813516906020013561048a565b3480156102e557600080fd5b50610176600480360360408110156102fc57600080fd5b50600160a060020a0381351690602001356104c6565b34801561031e57600080fd5b5061019f6004803603604081101561033557600080fd5b50600160a060020a03813581169160200135166104d3565b60408051808201909152600d81527f4b61726d612046696e616e636500000000000000000000000000000000000000602082015281565b60006103913384846104fe565b50600192915050565b60025490565b60006103ad84848461066b565b600160a060020a0384166000908152600160209081526040808320338085529252909120546103ed9186916103e8908663ffffffff61082f16565b6104fe565b5060019392505050565b601281565b336000818152600160209081526040808320600160a060020a038716845290915281205490916103919185906103e8908663ffffffff61088f16565b600160a060020a031660009081526020819052604090205490565b60408051808201909152600381527f4b46490000000000000000000000000000000000000000000000000000000000602082015281565b336000818152600160209081526040808320600160a060020a038716845290915281205490916103919185906103e8908663ffffffff61082f16565b600061039133848461066b565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b600160a060020a0383161515610583576040805160e560020a62461bcd028152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0382161515610609576040805160e560020a62461bcd02815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600160a060020a03831615156106f1576040805160e560020a62461bcd02815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0382161515610777576040805160e560020a62461bcd02815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0383166000908152602081905260409020546107a0908263ffffffff61082f16565b600160a060020a0380851660009081526020819052604080822093909355908416815220546107d5908263ffffffff61088f16565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600082821115610889576040805160e560020a62461bcd02815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000828201838110156108ec576040805160e560020a62461bcd02815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b939250505056fea165627a7a723058209339ef5b2e25ba12675510675acbcefeac4b6cd1ab5db6b2fb4c5158b647ac440029000000000000000000000000000000000000000000006ca1c92539831ea00000

Deployed Bytecode

0x6080604052600436106100ae5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100b3578063095ea7b31461013d57806318160ddd1461018a57806323b872dd146101b1578063313ce567146101f4578063395093511461021f57806370a082311461025857806395d89b411461028b578063a457c2d7146102a0578063a9059cbb146102d9578063dd62ed3e14610312575b600080fd5b3480156100bf57600080fd5b506100c861034d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101025781810151838201526020016100ea565b50505050905090810190601f16801561012f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014957600080fd5b506101766004803603604081101561016057600080fd5b50600160a060020a038135169060200135610384565b604080519115158252519081900360200190f35b34801561019657600080fd5b5061019f61039a565b60408051918252519081900360200190f35b3480156101bd57600080fd5b50610176600480360360608110156101d457600080fd5b50600160a060020a038135811691602081013590911690604001356103a0565b34801561020057600080fd5b506102096103f7565b6040805160ff9092168252519081900360200190f35b34801561022b57600080fd5b506101766004803603604081101561024257600080fd5b50600160a060020a0381351690602001356103fc565b34801561026457600080fd5b5061019f6004803603602081101561027b57600080fd5b5035600160a060020a0316610438565b34801561029757600080fd5b506100c8610453565b3480156102ac57600080fd5b50610176600480360360408110156102c357600080fd5b50600160a060020a03813516906020013561048a565b3480156102e557600080fd5b50610176600480360360408110156102fc57600080fd5b50600160a060020a0381351690602001356104c6565b34801561031e57600080fd5b5061019f6004803603604081101561033557600080fd5b50600160a060020a03813581169160200135166104d3565b60408051808201909152600d81527f4b61726d612046696e616e636500000000000000000000000000000000000000602082015281565b60006103913384846104fe565b50600192915050565b60025490565b60006103ad84848461066b565b600160a060020a0384166000908152600160209081526040808320338085529252909120546103ed9186916103e8908663ffffffff61082f16565b6104fe565b5060019392505050565b601281565b336000818152600160209081526040808320600160a060020a038716845290915281205490916103919185906103e8908663ffffffff61088f16565b600160a060020a031660009081526020819052604090205490565b60408051808201909152600381527f4b46490000000000000000000000000000000000000000000000000000000000602082015281565b336000818152600160209081526040808320600160a060020a038716845290915281205490916103919185906103e8908663ffffffff61082f16565b600061039133848461066b565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b600160a060020a0383161515610583576040805160e560020a62461bcd028152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0382161515610609576040805160e560020a62461bcd02815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600160a060020a03831615156106f1576040805160e560020a62461bcd02815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0382161515610777576040805160e560020a62461bcd02815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0383166000908152602081905260409020546107a0908263ffffffff61082f16565b600160a060020a0380851660009081526020819052604080822093909355908416815220546107d5908263ffffffff61088f16565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600082821115610889576040805160e560020a62461bcd02815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000828201838110156108ec576040805160e560020a62461bcd02815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b939250505056fea165627a7a723058209339ef5b2e25ba12675510675acbcefeac4b6cd1ab5db6b2fb4c5158b647ac440029

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000006ca1c92539831ea00000

-----Decoded View---------------
Arg [0] : totalSupply (uint256): 513000000000000000000000

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000000000000000000000006ca1c92539831ea00000


Deployed Bytecode Sourcemap

19782:315:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19864:45;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19864:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;19864:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9095:148;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9095:148:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;9095:148:0;;;;;;;;;;;;;;;;;;;;;;;;;;;8118:91;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8118:91:0;;;;;;;;;;;;;;;;;;;;9714:256;;8:9:-1;5:2;;;30:1;27;20:12;5:2;9714:256:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;9714:256:0;;;;;;;;;;;;;;;;;;19960:35;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19960:35:0;;;;;;;;;;;;;;;;;;;;;;;10379:206;;8:9:-1;5:2;;;30:1;27;20:12;5:2;10379:206:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;10379:206:0;;;;;;;;;8272:110;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8272:110:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;8272:110:0;-1:-1:-1;;;;;8272:110:0;;;19916:37;;8:9:-1;5:2;;;30:1;27;20:12;5:2;19916:37:0;;;;11088:216;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11088:216:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;11088:216:0;;;;;;;;;8595:156;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8595:156:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;8595:156:0;;;;;;;;;8814:134;;8:9:-1;5:2;;;30:1;27;20:12;5:2;8814:134:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;8814:134:0;;;;;;;;;;;19864:45;;;;;;;;;;;;;;;;;;;:::o;9095:148::-;9160:4;9177:36;9186:10;9198:7;9207:5;9177:8;:36::i;:::-;-1:-1:-1;9231:4:0;9095:148;;;;:::o;8118:91::-;8189:12;;8118:91;:::o;9714:256::-;9803:4;9820:36;9830:6;9838:9;9849:6;9820:9;:36::i;:::-;-1:-1:-1;;;;;9896:19:0;;;;;;:11;:19;;;;;;;;9884:10;9896:31;;;;;;;;;9867:73;;9876:6;;9896:43;;9932:6;9896:43;:35;:43;:::i;:::-;9867:8;:73::i;:::-;-1:-1:-1;9958:4:0;9714:256;;;;;:::o;19960:35::-;19993:2;19960:35;:::o;10379:206::-;10485:10;10459:4;10506:23;;;:11;:23;;;;;;;;-1:-1:-1;;;;;10506:32:0;;;;;;;;;;10459:4;;10476:79;;10497:7;;10506:48;;10543:10;10506:48;:36;:48;:::i;8272:110::-;-1:-1:-1;;;;;8356:18:0;8329:7;8356:18;;;;;;;;;;;;8272:110::o;19916:37::-;;;;;;;;;;;;;;;;;;;:::o;11088:216::-;11199:10;11173:4;11220:23;;;:11;:23;;;;;;;;-1:-1:-1;;;;;11220:32:0;;;;;;;;;;11173:4;;11190:84;;11211:7;;11220:53;;11257:15;11220:53;:36;:53;:::i;8595:156::-;8664:4;8681:40;8691:10;8703:9;8714:6;8681:9;:40::i;8814:134::-;-1:-1:-1;;;;;8913:18:0;;;8886:7;8913:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;8814:134::o;13890:335::-;-1:-1:-1;;;;;13983:19:0;;;;13975:68;;;;;-1:-1:-1;;;;;13975:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14062:21:0;;;;14054:68;;;;;-1:-1:-1;;;;;14054:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14135:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:35;;;14186:31;;;;;;;;;;;;;;;;;13890:335;;;:::o;11794:429::-;-1:-1:-1;;;;;11892:20:0;;;;11884:70;;;;;-1:-1:-1;;;;;11884:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;11973:23:0;;;;11965:71;;;;;-1:-1:-1;;;;;11965:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;12069:17:0;;:9;:17;;;;;;;;;;;:29;;12091:6;12069:29;:21;:29;:::i;:::-;-1:-1:-1;;;;;12049:17:0;;;:9;:17;;;;;;;;;;;:49;;;;12132:20;;;;;;;:32;;12157:6;12132:32;:24;:32;:::i;:::-;-1:-1:-1;;;;;12109:20:0;;;:9;:20;;;;;;;;;;;;:55;;;;12180:35;;;;;;;12109:20;;12180:35;;;;;;;;;;;;;11794:429;;;:::o;4240:184::-;4298:7;4326:6;;;;4318:49;;;;;-1:-1:-1;;;;;4318:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4390:5:0;;;4240:184::o;3784:181::-;3842:7;3874:5;;;3898:6;;;;3890:46;;;;;-1:-1:-1;;;;;3890:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;3956:1;3784:181;-1:-1:-1;;;3784:181:0:o

Swarm Source

bzzr://9339ef5b2e25ba12675510675acbcefeac4b6cd1ab5db6b2fb4c5158b647ac44

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

Finance allows people to 'invest' in others via its DeFi protocol for peer-to-peer giving.

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.