Polygon Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator:
Sponsored
Latest 19 from a total of 19 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Release Tokens | 16612296 | 995 days ago | IN | 0 MATIC | 0.00004954 | ||||
Release | 16574668 | 996 days ago | IN | 0 MATIC | 0.00007347 | ||||
Release | 16574640 | 996 days ago | IN | 0 MATIC | 0.0000982 | ||||
Release | 16574637 | 996 days ago | IN | 0 MATIC | 0.00008847 | ||||
Release | 16574632 | 996 days ago | IN | 0 MATIC | 0.0000982 | ||||
Deposit | 16566711 | 996 days ago | IN | 0 MATIC | 0.00077081 | ||||
Release Tokens | 16456749 | 999 days ago | IN | 0 MATIC | 0.00004954 | ||||
Release Tokens | 16456728 | 999 days ago | IN | 0 MATIC | 0.00004954 | ||||
Release Tokens | 16456708 | 999 days ago | IN | 0 MATIC | 0.00005499 | ||||
Release Tokens | 16456692 | 999 days ago | IN | 0 MATIC | 0.00005499 | ||||
Release | 16404942 | 1000 days ago | IN | 0 MATIC | 0.00009057 | ||||
Release | 16404881 | 1000 days ago | IN | 0 MATIC | 0.00010557 | ||||
Release | 16404817 | 1000 days ago | IN | 0 MATIC | 0.00008847 | ||||
Release | 16404756 | 1000 days ago | IN | 0 MATIC | 0.00010557 | ||||
Deposit | 16404590 | 1000 days ago | IN | 0 MATIC | 0.0007536 | ||||
Deposit | 16404472 | 1000 days ago | IN | 0 MATIC | 0.00073861 | ||||
Deposit | 16404439 | 1000 days ago | IN | 0 MATIC | 0.00073857 | ||||
Deposit | 16404341 | 1000 days ago | IN | 0 MATIC | 0.00078774 | ||||
0x61010060 | 16403279 | 1000 days ago | IN | Create: YieldFarming | 0 MATIC | 0.00404658 |
Latest 6 internal transactions
Parent Txn Hash | Block | From | To | Value | ||
---|---|---|---|---|---|---|
16566711 | 996 days ago | Contract Creation | 0 MATIC | |||
16404590 | 1000 days ago | Contract Creation | 0 MATIC | |||
16404472 | 1000 days ago | Contract Creation | 0 MATIC | |||
16404439 | 1000 days ago | Contract Creation | 0 MATIC | |||
16404341 | 1000 days ago | Contract Creation | 0 MATIC | |||
16403279 | 1000 days ago | Contract Creation | 0 MATIC |
Loading...
Loading
Contract Name:
YieldFarming
Compiler Version
v0.8.0+commit.c7dfd78e
Contract Source Code (Solidity)
/** *Submitted for verification at polygonscan.com on 2021-07-02 */ // Sources flattened with hardhat v2.4.1 https://hardhat.org // File @openzeppelin/contracts/utils/[email protected] // SPDX-License-Identifier: MIT AND BSD-4-Clause pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File @openzeppelin/contracts/access/[email protected] pragma solidity ^0.8.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. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the 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 virtual 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 virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File @openzeppelin/contracts/token/ERC20/[email protected] pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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. * * 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 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/utils/[email protected] pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] pragma solidity ^0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File contracts/Timestamp.sol pragma solidity ^0.8.0; contract Timestamp { function getTimestamp() public view returns (uint256){ // solhint-disable-next-line not-rely-on-time return block.timestamp; } } // File contracts/TokenTimeLock.sol pragma solidity ^0.8.0; /** * @dev A token holder contract that will allow a beneficiary to extract the * tokens after a given release time. * * Useful for simple vesting schedules like "advisors get all of their tokens * after 1 year". */ contract TokenTimeLock is Ownable { using SafeERC20 for IERC20; // ERC20 basic token contract being held IERC20 immutable private _token; // beneficiary of tokens after they are released address immutable private _beneficiary; // timestamp when token release is enabled uint256 immutable private _releaseTime; Timestamp private timestamp; constructor (Timestamp _timestamp, IERC20 token_, address beneficiary_, uint256 releaseTime_) { timestamp = _timestamp; // solhint-disable-next-line not-rely-on-time, reason-string require(releaseTime_ > timestamp.getTimestamp(), "TokenTimeLock: release time is before current time"); _token = token_; _beneficiary = beneficiary_; _releaseTime = releaseTime_; } /** * @return the token being held. */ function token() public view virtual returns (IERC20) { return _token; } /** * @return the beneficiary of the tokens. */ function beneficiary() public view virtual returns (address) { return _beneficiary; } /** * @return the time when the tokens are released. */ function releaseTime() public view virtual returns (uint256) { return _releaseTime; } /** * @notice Transfers tokens held by timelock to beneficiary. */ function release() public virtual onlyOwner { // solhint-disable-next-line not-rely-on-time, reason-string require(timestamp.getTimestamp() >= releaseTime(), "TokenTimeLock: current time is before release time"); uint256 amount = token().balanceOf(address(this)); // solhint-disable-next-line reason-string require(amount > 0, "TokenTimeLock: no tokens to release"); token().safeTransfer(beneficiary(), amount); } } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File @openzeppelin/contracts/token/ERC20/[email protected] pragma solidity ^0.8.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 {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * 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 Context, IERC20, IERC20Metadata { mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The defaut value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor (string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override 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 virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); 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 `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); _approve(sender, _msgSender(), currentAllowance - 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 virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + 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 virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); _approve(_msgSender(), spender, currentAllowance - 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 virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); _balances[sender] = senderBalance - amount; _balances[recipient] += 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 virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); } /** * @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(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); _balances[account] = accountBalance - amount; _totalSupply -= amount; emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This 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 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] pragma solidity ^0.8.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 currentAllowance = allowance(account, _msgSender()); require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance"); _approve(account, _msgSender(), currentAllowance - amount); _burn(account, amount); } } // File contracts/YieldFarmingToken.sol pragma solidity >=0.8.0 <0.9.0; contract YieldFarmingToken is ERC20Burnable, Ownable { constructor ( string memory name, string memory symbol // solhint-disable-next-line no-empty-blocks ) ERC20(name, symbol) { } function mint(address recipient, uint amount) public onlyOwner{ _mint(recipient, amount); } } // File contracts/abdk-libraries-solidity/ABDKMathQuad.sol /* * ABDK Math Quad Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.8.0; /** * Smart contract library of mathematical functions operating with IEEE 754 * quadruple-precision binary floating-point numbers (quadruple precision * numbers). As long as quadruple precision numbers are 16-bytes long, they are * represented by bytes16 type. */ library ABDKMathQuad { /* * 0. */ bytes16 private constant POSITIVE_ZERO = 0x00000000000000000000000000000000; /* * -0. */ bytes16 private constant NEGATIVE_ZERO = 0x80000000000000000000000000000000; /* * +Infinity. */ bytes16 private constant POSITIVE_INFINITY = 0x7FFF0000000000000000000000000000; /* * -Infinity. */ bytes16 private constant NEGATIVE_INFINITY = 0xFFFF0000000000000000000000000000; /* * -Log(e)/log(2) */ bytes16 private constant LOG_BASE_2_E = 0x3FFF71547652B82FE1777D0FFDA0D23A; /* * -log(2)/Log(e) */ bytes16 private constant LN_2 = 0x3FFE62E42FEFA39EF35793C7673007E5; /* * Canonical NAN value. */ bytes16 private constant NAN = 0x7FFF8000000000000000000000000000; /** * Convert signed 256-bit integer number into quadruple precision number. * * @param x signed 256-bit integer number * @return quadruple precision number */ function fromInt (int256 x) public pure returns (bytes16) { unchecked { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint256 (x > 0 ? x : -x); uint256 msb = mostSignificantBit (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } } /** * Convert quadruple precision number into signed 256-bit integer number * rounding towards zero. Revert on overflow. * * @param x quadruple precision number * @return signed 256-bit integer number */ function toInt (bytes16 x) public pure returns (int256) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16638, "Overflow!"); // Overflow if (exponent < 16383) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000, "result out of bounds!"); return -int256 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, "result out of bounds!"); return int256 (result); } } } /** * Convert unsigned 256-bit integer number into quadruple precision number. * * @param x unsigned 256-bit integer number * @return quadruple precision number */ function fromUInt (uint256 x) public pure returns (bytes16) { unchecked { if (x == 0) return bytes16 (0); else { uint256 result = x; uint256 msb = mostSignificantBit (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; return bytes16 (uint128 (result)); } } } /** * Convert quadruple precision number into unsigned 256-bit integer number * rounding towards zero. Revert on underflow. Note, that negative floating * point numbers in range (-1.0 .. 0.0) may be converted to unsigned integer * without error, because they are rounded to zero. * * @param x quadruple precision number * @return unsigned 256-bit integer number */ function toUInt (bytes16 x) public pure returns (uint256) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; if (exponent < 16383) return 0; // Underflow require (uint128 (x) < 0x80000000000000000000000000000000, "x out of bounds!"); // Negative require (exponent <= 16638, "Overflow!"); // Overflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; return result; } } /** * Convert signed 128.128 bit fixed point number into quadruple precision * number. * * @param x signed 128.128 bit fixed point number * @return quadruple precision number */ function from128x128 (int256 x) public pure returns (bytes16) { unchecked { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint256 (x > 0 ? x : -x); uint256 msb = mostSignificantBit (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16255 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } } /** * Convert quadruple precision number into signed 128.128 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 128.128 bit fixed point number */ function to128x128 (bytes16 x) public pure returns (int256) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16510, "Overflow!"); // Overflow if (exponent < 16255) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16367) result >>= 16367 - exponent; else if (exponent > 16367) result <<= exponent - 16367; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000, "result out of bounds!"); return -int256 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, "result out of bounds!"); return int256 (result); } } } /** * Convert signed 64.64 bit fixed point number into quadruple precision * number. * * @param x signed 64.64 bit fixed point number * @return quadruple precision number */ function from64x64 (int128 x) public pure returns (bytes16) { unchecked { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint128 (x > 0 ? x : -x); uint256 msb = mostSignificantBit (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16319 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } } /** * Convert quadruple precision number into signed 64.64 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 64.64 bit fixed point number */ function to64x64 (bytes16 x) public pure returns (int128) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16446, "Overflow!"); // Overflow if (exponent < 16319) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16431) result >>= 16431 - exponent; else if (exponent > 16431) result <<= exponent - 16431; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x80000000000000000000000000000000, "result out of bounds!"); return -int128 (int256 (result)); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, "result out of bounds!"); return int128 (int256 (result)); } } } /** * Convert octuple precision number into quadruple precision number. * * @param x octuple precision number * @return quadruple precision number */ function fromOctuple (bytes32 x) public pure returns (bytes16) { unchecked { bool negative = x & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0; uint256 exponent = uint256 (x) >> 236 & 0x7FFFF; uint256 significand = uint256 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFFF) { if (significand > 0) return NAN; else return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; } if (exponent > 278526) return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else if (exponent < 245649) return negative ? NEGATIVE_ZERO : POSITIVE_ZERO; else if (exponent < 245761) { significand = (significand | 0x100000000000000000000000000000000000000000000000000000000000) >> 245885 - exponent; exponent = 0; } else { significand >>= 124; exponent -= 245760; } uint128 result = uint128 (significand | exponent << 112); if (negative) result |= 0x80000000000000000000000000000000; return bytes16 (result); } } /** * Convert quadruple precision number into octuple precision number. * * @param x quadruple precision number * @return octuple precision number */ function toOctuple (bytes16 x) public pure returns (bytes32) { unchecked { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; uint256 result = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) exponent = 0x7FFFF; // Infinity or NAN else if (exponent == 0) { if (result > 0) { uint256 msb = mostSignificantBit (result); result = result << 236 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 245649 + msb; } } else { result <<= 124; exponent += 245760; } result |= exponent << 236; if (uint128 (x) >= 0x80000000000000000000000000000000) result |= 0x8000000000000000000000000000000000000000000000000000000000000000; return bytes32 (result); } } /** * Convert double precision number into quadruple precision number. * * @param x double precision number * @return quadruple precision number */ function fromDouble (bytes8 x) public pure returns (bytes16) { unchecked { uint256 exponent = uint64 (x) >> 52 & 0x7FF; uint256 result = uint64 (x) & 0xFFFFFFFFFFFFF; if (exponent == 0x7FF) exponent = 0x7FFF; // Infinity or NAN else if (exponent == 0) { if (result > 0) { uint256 msb = mostSignificantBit (result); result = result << 112 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 15309 + msb; } } else { result <<= 60; exponent += 15360; } result |= exponent << 112; if (x & 0x8000000000000000 > 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into double precision number. * * @param x quadruple precision number * @return double precision number */ function toDouble (bytes16 x) public pure returns (bytes8) { unchecked { bool negative = uint128 (x) >= 0x80000000000000000000000000000000; uint256 exponent = uint128 (x) >> 112 & 0x7FFF; uint256 significand = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) { if (significand > 0) return 0x7FF8000000000000; // NAN else return negative ? bytes8 (0xFFF0000000000000) : // -Infinity bytes8 (0x7FF0000000000000); // Infinity } if (exponent > 17406) return negative ? bytes8 (0xFFF0000000000000) : // -Infinity bytes8 (0x7FF0000000000000); // Infinity else if (exponent < 15309) return negative ? bytes8 (0x8000000000000000) : // -0 bytes8 (0x0000000000000000); // 0 else if (exponent < 15361) { significand = (significand | 0x10000000000000000000000000000) >> 15421 - exponent; exponent = 0; } else { significand >>= 60; exponent -= 15360; } uint64 result = uint64 (significand | exponent << 52); if (negative) result |= 0x8000000000000000; return bytes8 (result); } } /** * Test whether given quadruple precision number is NAN. * * @param x quadruple precision number * @return true if x is NAN, false otherwise */ function isNAN (bytes16 x) public pure returns (bool) { unchecked { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF > 0x7FFF0000000000000000000000000000; } } /** * Test whether given quadruple precision number is positive or negative * infinity. * * @param x quadruple precision number * @return true if x is positive or negative infinity, false otherwise */ function isInfinity (bytes16 x) public pure returns (bool) { unchecked { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x7FFF0000000000000000000000000000; } } /** * Calculate sign of x, i.e. -1 if x is negative, 0 if x if zero, and 1 if x * is positive. Note that sign (-0) is zero. Revert if x is NAN. * * @param x quadruple precision number * @return sign of x */ function sign (bytes16 x) public pure returns (int8) { unchecked { uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteX <= 0x7FFF0000000000000000000000000000, "Can't be NAN!"); // Not NAN if (absoluteX == 0) return 0; else if (uint128 (x) >= 0x80000000000000000000000000000000) return -1; else return 1; } } /** * Calculate sign (x - y). Revert if either argument is NAN, or both * arguments are infinities of the same sign. * * @param x quadruple precision number * @param y quadruple precision number * @return sign (x - y) */ function cmp (bytes16 x, bytes16 y) public pure returns (int8) { unchecked { uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteX <= 0x7FFF0000000000000000000000000000, "absoluteX out of bounds!"); // Not NAN uint128 absoluteY = uint128 (y) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteY <= 0x7FFF0000000000000000000000000000, "absoluteY out of bounds!"); // Not NAN // Not infinities of the same sign require (x != y || absoluteX < 0x7FFF0000000000000000000000000000, "Can't be same signed infinites!"); if (x == y) return 0; else { bool negativeX = uint128 (x) >= 0x80000000000000000000000000000000; bool negativeY = uint128 (y) >= 0x80000000000000000000000000000000; if (negativeX) { if (negativeY) return absoluteX > absoluteY ? -1 : int8 (1); else return -1; } else { if (negativeY) return 1; else return absoluteX > absoluteY ? int8 (1) : -1; } } } } /** * Test whether x equals y. NAN, infinity, and -infinity are not equal to * anything. * * @param x quadruple precision number * @param y quadruple precision number * @return true if x equals to y, false otherwise */ function eq (bytes16 x, bytes16 y) public pure returns (bool) { unchecked { if (x == y) { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF < 0x7FFF0000000000000000000000000000; } else return false; } } /** * Calculate x + y. Special values behave in the following way: * * NAN + x = NAN for any x. * Infinity + x = Infinity for any finite x. * -Infinity + x = -Infinity for any finite x. * Infinity + Infinity = Infinity. * -Infinity + -Infinity = -Infinity. * Infinity + -Infinity = -Infinity + Infinity = NAN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function add (bytes16 x, bytes16 y) public pure returns (bytes16) { unchecked { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x; else return NAN; } else return x; } else if (yExponent == 0x7FFF) return y; else { bool xSign = uint128 (x) >= 0x80000000000000000000000000000000; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; bool ySign = uint128 (y) >= 0x80000000000000000000000000000000; uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return y == NEGATIVE_ZERO ? POSITIVE_ZERO : y; else if (ySignifier == 0) return x == NEGATIVE_ZERO ? POSITIVE_ZERO : x; else { int256 delta = int256 (xExponent) - int256 (yExponent); if (xSign == ySign) { if (delta > 112) return x; else if (delta > 0) ySignifier >>= uint256 (delta); else if (delta < -112) return y; else if (delta < 0) { xSignifier >>= uint256 (-delta); xExponent = yExponent; } xSignifier += ySignifier; if (xSignifier >= 0x20000000000000000000000000000) { xSignifier >>= 1; xExponent += 1; } if (xExponent == 0x7FFF) return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else { if (xSignifier < 0x10000000000000000000000000000) xExponent = 0; else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; return bytes16 (uint128 ( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier)); } } else { if (delta > 0) { xSignifier <<= 1; xExponent -= 1; } else if (delta < 0) { ySignifier <<= 1; xExponent = yExponent - 1; } if (delta > 112) ySignifier = 1; else if (delta > 1) ySignifier = (ySignifier - 1 >> uint256 (delta - 1)) + 1; else if (delta < -112) xSignifier = 1; else if (delta < -1) xSignifier = (xSignifier - 1 >> uint256 (-delta - 1)) + 1; if (xSignifier >= ySignifier) xSignifier -= ySignifier; else { xSignifier = ySignifier - xSignifier; xSign = ySign; } if (xSignifier == 0) return POSITIVE_ZERO; uint256 msb = mostSignificantBit (xSignifier); if (msb == 113) { xSignifier = xSignifier >> 1 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent += 1; } else if (msb < 112) { uint256 shift = 112 - msb; if (xExponent > shift) { xSignifier = xSignifier << shift & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent -= shift; } else { xSignifier <<= xExponent - 1; xExponent = 0; } } else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF) return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else return bytes16 (uint128 ( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier)); } } } } } /** * Calculate x - y. Special values behave in the following way: * * NAN - x = NAN for any x. * Infinity - x = Infinity for any finite x. * -Infinity - x = -Infinity for any finite x. * Infinity - -Infinity = Infinity. * -Infinity - Infinity = -Infinity. * Infinity - Infinity = -Infinity - -Infinity = NAN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function sub (bytes16 x, bytes16 y) public pure returns (bytes16) { unchecked { return add (x, y ^ 0x80000000000000000000000000000000); } } /** * Calculate x * y. Special values behave in the following way: * * NAN * x = NAN for any x. * Infinity * x = Infinity for any finite positive x. * Infinity * x = -Infinity for any finite negative x. * -Infinity * x = -Infinity for any finite positive x. * -Infinity * x = Infinity for any finite negative x. * Infinity * 0 = NAN. * -Infinity * 0 = NAN. * Infinity * Infinity = Infinity. * Infinity * -Infinity = -Infinity. * -Infinity * Infinity = -Infinity. * -Infinity * -Infinity = Infinity. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function mul (bytes16 x, bytes16 y) public pure returns (bytes16) { unchecked { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x ^ y & 0x80000000000000000000000000000000; else if (x ^ y == 0x80000000000000000000000000000000) return x | y; else return NAN; } else { if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NAN; else return x ^ y & 0x80000000000000000000000000000000; } } else if (yExponent == 0x7FFF) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NAN; else return y ^ x & 0x80000000000000000000000000000000; } else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; xSignifier *= ySignifier; if (xSignifier == 0) return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; xExponent += yExponent; uint256 msb = xSignifier >= 0x200000000000000000000000000000000000000000000000000000000 ? 225 : xSignifier >= 0x100000000000000000000000000000000000000000000000000000000 ? 224 : mostSignificantBit (xSignifier); if (xExponent + msb < 16496) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb < 16608) { // Subnormal if (xExponent < 16496) xSignifier >>= 16496 - xExponent; else if (xExponent > 16496) xSignifier <<= xExponent - 16496; xExponent = 0; } else if (xExponent + msb > 49373) { xExponent = 0x7FFF; xSignifier = 0; } else { if (msb > 112) xSignifier >>= msb - 112; else if (msb < 112) xSignifier <<= 112 - msb; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb - 16607; } return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier)); } } } /** * Calculate x / y. Special values behave in the following way: * * NAN / x = NAN for any x. * x / NAN = NAN for any x. * Infinity / x = Infinity for any finite non-negative x. * Infinity / x = -Infinity for any finite negative x including -0. * -Infinity / x = -Infinity for any finite non-negative x. * -Infinity / x = Infinity for any finite negative x including -0. * x / Infinity = 0 for any finite non-negative x. * x / -Infinity = -0 for any finite non-negative x. * x / Infinity = -0 for any finite non-negative x including -0. * x / -Infinity = 0 for any finite non-negative x including -0. * * Infinity / Infinity = NAN. * Infinity / -Infinity = -NAN. * -Infinity / Infinity = -NAN. * -Infinity / -Infinity = NAN. * * Division by zero behaves in the following way: * * x / 0 = Infinity for any finite positive x. * x / -0 = -Infinity for any finite positive x. * x / 0 = -Infinity for any finite negative x. * x / -0 = Infinity for any finite negative x. * 0 / 0 = NAN. * 0 / -0 = NAN. * -0 / 0 = NAN. * -0 / -0 = NAN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function div (bytes16 x, bytes16 y) public pure returns (bytes16) { unchecked { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) return NAN; else return x ^ y & 0x80000000000000000000000000000000; } else if (yExponent == 0x7FFF) { if (y & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF != 0) return NAN; else return POSITIVE_ZERO | (x ^ y) & 0x80000000000000000000000000000000; } else if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NAN; else return POSITIVE_INFINITY | (x ^ y) & 0x80000000000000000000000000000000; } else { uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) { if (xSignifier != 0) { uint shift = 226 - mostSignificantBit (xSignifier); xSignifier <<= shift; xExponent = 1; yExponent += shift - 114; } } else { xSignifier = (xSignifier | 0x10000000000000000000000000000) << 114; } xSignifier = xSignifier / ySignifier; if (xSignifier == 0) return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; assert (xSignifier >= 0x1000000000000000000000000000); uint256 msb = xSignifier >= 0x80000000000000000000000000000 ? mostSignificantBit (xSignifier) : xSignifier >= 0x40000000000000000000000000000 ? 114 : xSignifier >= 0x20000000000000000000000000000 ? 113 : 112; if (xExponent + msb > yExponent + 16497) { // Overflow xExponent = 0x7FFF; xSignifier = 0; } else if (xExponent + msb + 16380 < yExponent) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb + 16268 < yExponent) { // Subnormal if (xExponent + 16380 > yExponent) xSignifier <<= xExponent + 16380 - yExponent; else if (xExponent + 16380 < yExponent) xSignifier >>= yExponent - xExponent - 16380; xExponent = 0; } else { // Normal if (msb > 112) xSignifier >>= msb - 112; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb + 16269 - yExponent; } return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier)); } } } /** * Calculate -x. * * @param x quadruple precision number * @return quadruple precision number */ function neg (bytes16 x) public pure returns (bytes16) { unchecked { return x ^ 0x80000000000000000000000000000000; } } /** * Calculate |x|. * * @param x quadruple precision number * @return quadruple precision number */ function abs (bytes16 x) public pure returns (bytes16) { unchecked { return x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } } /** * Calculate square root of x. Return NAN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function sqrt (bytes16 x) public pure returns (bytes16) { unchecked { if (uint128 (x) > 0x80000000000000000000000000000000) return NAN; else { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) return x; else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return POSITIVE_ZERO; bool oddExponent = xExponent & 0x1 == 0; xExponent = xExponent + 16383 >> 1; if (oddExponent) { if (xSignifier >= 0x10000000000000000000000000000) xSignifier <<= 113; else { uint256 msb = mostSignificantBit (xSignifier); uint256 shift = (226 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } else { if (xSignifier >= 0x10000000000000000000000000000) xSignifier <<= 112; else { uint256 msb = mostSignificantBit (xSignifier); uint256 shift = (225 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } uint256 r = 0x10000000000000000000000000000; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; // Seven iterations should be enough uint256 r1 = xSignifier / r; if (r1 < r) r = r1; return bytes16 (uint128 (xExponent << 112 | r & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } } /** * Calculate binary logarithm of x. Return NAN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function logBase2 (bytes16 x) public pure returns (bytes16) { unchecked { if (uint128 (x) > 0x80000000000000000000000000000000) return NAN; else if (x == 0x3FFF0000000000000000000000000000) return POSITIVE_ZERO; else { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) return x; else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return NEGATIVE_INFINITY; bool resultNegative; uint256 resultExponent = 16495; uint256 resultSignifier; if (xExponent >= 0x3FFF) { resultNegative = false; resultSignifier = xExponent - 0x3FFF; xSignifier <<= 15; } else { resultNegative = true; if (xSignifier >= 0x10000000000000000000000000000) { resultSignifier = 0x3FFE - xExponent; xSignifier <<= 15; } else { uint256 msb = mostSignificantBit (xSignifier); resultSignifier = 16493 - msb; xSignifier <<= 127 - msb; } } if (xSignifier == 0x80000000000000000000000000000000) { if (resultNegative) resultSignifier += 1; uint256 shift = 112 - mostSignificantBit (resultSignifier); resultSignifier <<= shift; resultExponent -= shift; } else { uint256 bb = resultNegative ? 1 : 0; while (resultSignifier < 0x10000000000000000000000000000) { resultSignifier <<= 1; resultExponent -= 1; xSignifier *= xSignifier; uint256 b = xSignifier >> 255; resultSignifier += b ^ bb; xSignifier >>= 127 + b; } } return bytes16 (uint128 ((resultNegative ? 0x80000000000000000000000000000000 : 0) | resultExponent << 112 | resultSignifier & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } } /** * Calculate natural logarithm of x. Return NAN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function ln (bytes16 x) public pure returns (bytes16) { unchecked { return mul (logBase2 (x), LN_2); } } /** * Calculate 2^x. * * @param x quadruple precision number * @return quadruple precision number */ function powerBase2 (bytes16 x) public pure returns (bytes16) { unchecked { bool xNegative = uint128 (x) > 0x80000000000000000000000000000000; uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF && xSignifier != 0) return NAN; else if (xExponent > 16397) return xNegative ? POSITIVE_ZERO : POSITIVE_INFINITY; else if (xExponent < 16255) return 0x3FFF0000000000000000000000000000; else { if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xExponent > 16367) xSignifier <<= xExponent - 16367; else if (xExponent < 16367) xSignifier >>= 16367 - xExponent; if (xNegative && xSignifier > 0x406E00000000000000000000000000000000) return POSITIVE_ZERO; if (!xNegative && xSignifier > 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) return POSITIVE_INFINITY; uint256 resultExponent = xSignifier >> 128; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xNegative && xSignifier != 0) { xSignifier = ~xSignifier; resultExponent += 1; } uint256 resultSignifier = 0x80000000000000000000000000000000; if (xSignifier & 0x80000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; if (xSignifier & 0x40000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; if (xSignifier & 0x20000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; if (xSignifier & 0x10000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10B5586CF9890F6298B92B71842A98363 >> 128; if (xSignifier & 0x8000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; if (xSignifier & 0x4000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; if (xSignifier & 0x2000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; if (xSignifier & 0x1000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; if (xSignifier & 0x800000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; if (xSignifier & 0x400000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; if (xSignifier & 0x200000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; if (xSignifier & 0x100000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; if (xSignifier & 0x80000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; if (xSignifier & 0x40000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; if (xSignifier & 0x20000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000162E525EE054754457D5995292026 >> 128; if (xSignifier & 0x10000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000B17255775C040618BF4A4ADE83FC >> 128; if (xSignifier & 0x8000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; if (xSignifier & 0x4000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; if (xSignifier & 0x2000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000162E43F4F831060E02D839A9D16D >> 128; if (xSignifier & 0x1000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000B1721BCFC99D9F890EA06911763 >> 128; if (xSignifier & 0x800000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; if (xSignifier & 0x400000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; if (xSignifier & 0x200000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000162E430E5A18F6119E3C02282A5 >> 128; if (xSignifier & 0x100000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; if (xSignifier & 0x80000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; if (xSignifier & 0x40000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000002C5C8601CC6B9E94213C72737A >> 128; if (xSignifier & 0x20000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; if (xSignifier & 0x10000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; if (xSignifier & 0x8000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; if (xSignifier & 0x4000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; if (xSignifier & 0x2000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; if (xSignifier & 0x1000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000B17217F80F4EF5AADDA45554 >> 128; if (xSignifier & 0x800000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; if (xSignifier & 0x400000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; if (xSignifier & 0x200000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000162E42FEFB2FED257559BDAA >> 128; if (xSignifier & 0x100000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; if (xSignifier & 0x80000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; if (xSignifier & 0x40000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; if (xSignifier & 0x20000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000162E42FEFA494F1478FDE05 >> 128; if (xSignifier & 0x10000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000B17217F7D20CF927C8E94C >> 128; if (xSignifier & 0x8000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; if (xSignifier & 0x4000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000002C5C85FDF477B662B26945 >> 128; if (xSignifier & 0x2000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000162E42FEFA3AE53369388C >> 128; if (xSignifier & 0x1000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000B17217F7D1D351A389D40 >> 128; if (xSignifier & 0x800000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; if (xSignifier & 0x400000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; if (xSignifier & 0x200000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000162E42FEFA39FE95583C2 >> 128; if (xSignifier & 0x100000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; if (xSignifier & 0x80000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; if (xSignifier & 0x40000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000002C5C85FDF473E242EA38 >> 128; if (xSignifier & 0x20000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000162E42FEFA39F02B772C >> 128; if (xSignifier & 0x10000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000B17217F7D1CF7D83C1A >> 128; if (xSignifier & 0x8000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; if (xSignifier & 0x4000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000002C5C85FDF473DEA871F >> 128; if (xSignifier & 0x2000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000162E42FEFA39EF44D91 >> 128; if (xSignifier & 0x1000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000B17217F7D1CF79E949 >> 128; if (xSignifier & 0x800000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000058B90BFBE8E7BCE544 >> 128; if (xSignifier & 0x400000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000002C5C85FDF473DE6ECA >> 128; if (xSignifier & 0x200000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000162E42FEFA39EF366F >> 128; if (xSignifier & 0x100000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000B17217F7D1CF79AFA >> 128; if (xSignifier & 0x80000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000058B90BFBE8E7BCD6D >> 128; if (xSignifier & 0x40000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000002C5C85FDF473DE6B2 >> 128; if (xSignifier & 0x20000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000162E42FEFA39EF358 >> 128; if (xSignifier & 0x10000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000B17217F7D1CF79AB >> 128; if (xSignifier & 0x8000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000058B90BFBE8E7BCD5 >> 128; if (xSignifier & 0x4000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000002C5C85FDF473DE6A >> 128; if (xSignifier & 0x2000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000162E42FEFA39EF34 >> 128; if (xSignifier & 0x1000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000B17217F7D1CF799 >> 128; if (xSignifier & 0x800000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000058B90BFBE8E7BCC >> 128; if (xSignifier & 0x400000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000002C5C85FDF473DE5 >> 128; if (xSignifier & 0x200000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000162E42FEFA39EF2 >> 128; if (xSignifier & 0x100000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000B17217F7D1CF78 >> 128; if (xSignifier & 0x80000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000058B90BFBE8E7BB >> 128; if (xSignifier & 0x40000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000002C5C85FDF473DD >> 128; if (xSignifier & 0x20000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000162E42FEFA39EE >> 128; if (xSignifier & 0x10000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000B17217F7D1CF6 >> 128; if (xSignifier & 0x8000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000058B90BFBE8E7A >> 128; if (xSignifier & 0x4000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000002C5C85FDF473C >> 128; if (xSignifier & 0x2000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000162E42FEFA39D >> 128; if (xSignifier & 0x1000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000B17217F7D1CE >> 128; if (xSignifier & 0x800000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000058B90BFBE8E6 >> 128; if (xSignifier & 0x400000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000002C5C85FDF472 >> 128; if (xSignifier & 0x200000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000162E42FEFA38 >> 128; if (xSignifier & 0x100000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000B17217F7D1B >> 128; if (xSignifier & 0x80000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000058B90BFBE8D >> 128; if (xSignifier & 0x40000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000002C5C85FDF46 >> 128; if (xSignifier & 0x20000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000162E42FEFA2 >> 128; if (xSignifier & 0x10000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000B17217F7D0 >> 128; if (xSignifier & 0x8000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000058B90BFBE7 >> 128; if (xSignifier & 0x4000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000002C5C85FDF3 >> 128; if (xSignifier & 0x2000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000162E42FEF9 >> 128; if (xSignifier & 0x1000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000B17217F7C >> 128; if (xSignifier & 0x800000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000058B90BFBD >> 128; if (xSignifier & 0x400000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000002C5C85FDE >> 128; if (xSignifier & 0x200000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000162E42FEE >> 128; if (xSignifier & 0x100000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000B17217F6 >> 128; if (xSignifier & 0x80000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000058B90BFA >> 128; if (xSignifier & 0x40000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000002C5C85FC >> 128; if (xSignifier & 0x20000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000162E42FD >> 128; if (xSignifier & 0x10000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000B17217E >> 128; if (xSignifier & 0x8000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000058B90BE >> 128; if (xSignifier & 0x4000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000002C5C85E >> 128; if (xSignifier & 0x2000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000162E42E >> 128; if (xSignifier & 0x1000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000B17216 >> 128; if (xSignifier & 0x800000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000058B90A >> 128; if (xSignifier & 0x400000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000002C5C84 >> 128; if (xSignifier & 0x200000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000162E41 >> 128; if (xSignifier & 0x100000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000B1720 >> 128; if (xSignifier & 0x80000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000058B8F >> 128; if (xSignifier & 0x40000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000002C5C7 >> 128; if (xSignifier & 0x20000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000162E3 >> 128; if (xSignifier & 0x10000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000B171 >> 128; if (xSignifier & 0x8000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000058B8 >> 128; if (xSignifier & 0x4000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000002C5B >> 128; if (xSignifier & 0x2000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000162D >> 128; if (xSignifier & 0x1000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000B16 >> 128; if (xSignifier & 0x800 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000058A >> 128; if (xSignifier & 0x400 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000002C4 >> 128; if (xSignifier & 0x200 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000161 >> 128; if (xSignifier & 0x100 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000000B0 >> 128; if (xSignifier & 0x80 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000057 >> 128; if (xSignifier & 0x40 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000002B >> 128; if (xSignifier & 0x20 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000015 >> 128; if (xSignifier & 0x10 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000000A >> 128; if (xSignifier & 0x8 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000004 >> 128; if (xSignifier & 0x4 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000001 >> 128; if (!xNegative) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent += 0x3FFF; } else if (resultExponent <= 0x3FFE) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent = 0x3FFF - resultExponent; } else { resultSignifier = resultSignifier >> resultExponent - 16367; resultExponent = 0; } return bytes16 (uint128 (resultExponent << 112 | resultSignifier)); } } } /** * Calculate x^y. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function pow (bytes16 x, bytes16 y) public pure returns (bytes16) { unchecked { return powerBase2(mul(y, logBase2(x))); } } /** * Calculate e^x. * * @param x quadruple precision number * @return quadruple precision number */ function exp (bytes16 x) public pure returns (bytes16) { unchecked { return powerBase2 (mul (x, LOG_BASE_2_E)); } } /** * Get index of the most significant non-zero bit in binary representation of * x. Reverts if x is zero. * * @return index of the most significant non-zero bit in binary representation * of x */ function mostSignificantBit (uint256 x) private pure returns (uint256) { unchecked { require (x > 0, "x out of bounds!"); uint256 result = 0; if (x >= 0x100000000000000000000000000000000) { x >>= 128; result += 128; } if (x >= 0x10000000000000000) { x >>= 64; result += 64; } if (x >= 0x100000000) { x >>= 32; result += 32; } if (x >= 0x10000) { x >>= 16; result += 16; } if (x >= 0x100) { x >>= 8; result += 8; } if (x >= 0x10) { x >>= 4; result += 4; } if (x >= 0x4) { x >>= 2; result += 2; } if (x >= 0x2) result += 1; // No need to shift x anymore return result; } } } // File contracts/RewardCalculator.sol pragma solidity >=0.8.0 <0.9.0; contract RewardCalculator{ using ABDKMathQuad for bytes16; bytes16 private immutable oneDay; bytes16 private immutable half; constructor (){ oneDay = ABDKMathQuad.fromUInt(1 days); half = ABDKMathQuad.fromUInt(1).div(ABDKMathQuad.fromUInt(2)); } function calculateQuantity(uint inputValue, bytes16 multiplier, bytes16 interestRate, uint elapsedTime) public view returns(uint){ return multiplier.mul(ABDKMathQuad.fromUInt(inputValue)) .div( ABDKMathQuad.fromUInt(1) .add(interestRate) .pow( ABDKMathQuad.fromUInt(elapsedTime) .div(oneDay) ) ) .add(half) // rounding .toUInt(); } } // File @openzeppelin/contracts/utils/math/[email protected] pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, 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) { 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) { return a - b; } /** * @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) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards 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). * * 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, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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, string memory errorMessage) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } } // File contracts/PaymentSplitter.sol pragma solidity ^0.8.0; /** * @title PaymentSplitter * @dev This contract allows to split Token payments among a group of accounts. The sender does not need to be aware * that the Tokens will be split in this way, since it is handled transparently by the contract. * * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each * account to a number of shares. Of all the Tokens that this contract receives, each account will then be able to claim * an amount proportional to the percentage of total shares they were assigned. * * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release} * function. */ struct Record { uint256 shares; uint256 released; } struct RecordArchive { mapping(address => Record) records; address[] addresses; } contract PaymentSplitter is Context, Ownable { using SafeERC20 for IERC20; event PayeeAdded(address account, uint256 shares); event PayeeUpdated(address account, int256 shares); event PayeeRemoved(address account); event PaymentReleased(address to, uint256 amount); event AcceptedTokenDeposit(address depositor, uint amount); event SharesTransferred(address transferrer, address to, uint sharesAmount); IERC20 immutable private acceptedToken; RecordArchive private payeeArchive; /** * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at * the matching position in the `shares` array. * * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no * duplicates in `payees`. */ constructor (IERC20 _acceptedToken, address[] memory _payees, uint256[] memory _shares) { // solhint-disable-next-line max-line-length, reason-string require(_payees.length == _shares.length, "PaymentSplitter: payees and shares length mismatch"); require(_payees.length > 0, "PaymentSplitter: no payees"); for (uint256 i = 0; i < _payees.length; i++) { addPayee(_payees[i], _shares[i]); } acceptedToken = _acceptedToken; } /** * @dev The Tokens received will be logged with {PaymentReceived} events. Note that these events are not fully * reliable: it's possible for a contract to receive Tokens without triggering this function. This only affects the * reliability of the events, and not the actual splitting of Tokens. * * To learn more about this see the Solidity documentation for * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback * functions]. */ function deposit(address depositor, uint amount) internal { acceptedToken.safeTransferFrom(depositor, address(this), amount); emit AcceptedTokenDeposit(depositor, amount); } /** * @dev Getter for the total shares held by payees. */ function totalShares() public view returns (uint256) { return shares(address(this)); } /** * @dev Getter for the total amount of Tokens already released. */ function totalReleased() public view returns (uint256) { return released(address(this)); } /** * @dev Getter for the amount of shares held by an account. */ function record(address account) public view returns (Record memory) { return payeeArchive.records[account]; } /** * @dev Getter for the amount of shares held by an account. */ function shares(address account) public view returns (uint256) { return record(account).shares; } /** * @dev Getter for the amount of Tokens already released to a payee. */ function released(address account) public view returns (uint256) { return record(account).released; } /** * @dev Getter for the address of the payee number `index`. */ function payee(uint256 index) public view returns (address) { return payeeArchive.addresses[index]; } /** * @dev Triggers a transfer to `account` of the amount of tokens they are owed, according to their percentage of the * total shares and their previous withdrawals. */ function release(address account) public virtual { // solhint-disable-next-line reason-string require(isPayee(account), "PaymentSplitter: account is not a payee"); uint256 totalReceived = acceptedToken.balanceOf(address(this)) + totalReleased(); uint256 payment = totalReceived * shares(account) / totalShares() - released(account); // solhint-disable-next-line reason-string require(payment != 0, "PaymentSplitter: account is not due payment"); payeeArchive.records[account].released += payment; payeeArchive.records[address(this)].released += payment; acceptedToken.safeTransfer(account, payment); emit PaymentReleased(account, payment); } function isPayee(address account) public view returns (bool){ return (shares(account) > 0); } /** * @dev Transfer shares. * @param to The address of the shares destinatary to transfer to. * @param sharesAmount The number of shares to be transfered by the transferrer. */ function transferShares(address to, uint256 sharesAmount) public { address transferrer = _msgSender(); // solhint-disable-next-line reason-string require(isPayee(transferrer), "PaymentSplitter: transferrer not a payee"); // solhint-disable-next-line reason-string require(shares(transferrer) >= sharesAmount, "PaymentSplitter: not enough shares balance"); // Deduct from transferrer shares balance _updatePayee(transferrer, shares(transferrer)-sharesAmount); if(isPayee(to)){ _updatePayee(to, shares(to)+sharesAmount); }else{ _addPayee(to, sharesAmount); } emit SharesTransferred(transferrer, to, sharesAmount); } /** * @dev Add a new payee to the contract. * @param account The address of the payee to add. * @param _shares The number of shares owned by the payee. */ function _updatePayee(address account, uint256 _shares) private { require(isPayee(account), "PaymentSplitter: not a payee"); if (_shares == 0) { _removePayee(account); return; } // solhint-disable-next-line reason-string require(shares(account) != _shares, "PaymentSplitter: account already has that many shares"); int256 delta = int256(_shares) - int256(shares(account)); payeeArchive.records[account].shares = _shares; payeeArchive.records[address(this)].shares = uint256(int256(payeeArchive.records[address(this)].shares) + delta); emit PayeeUpdated(account, delta); } /** * @dev Add a new payee to the contract. * @param account The address of the payee to add. * @param _shares The number of shares owned by the payee. */ function _addPayee(address account, uint256 _shares) private { // solhint-disable-next-line reason-string require(account != address(0), "PaymentSplitter: account is the zero address"); require(_shares > 0, "PaymentSplitter: shares are 0"); // solhint-disable-next-line reason-string require(!isPayee(account), "PaymentSplitter: account is already payee"); payeeArchive.addresses.push(account); payeeArchive.records[account].shares = _shares; payeeArchive.records[address(this)].shares += _shares; emit PayeeAdded(account, _shares); } /** * @dev Remove a payee from the contract. * @param account The address of the payee to remove. */ function _removePayee(address account) private { // solhint-disable-next-line reason-string require(payeeArchive.addresses.length > 0, "PaymentSplitter: empty payee list"); Record memory recordToBeRemoved = record(account); delete payeeArchive.records[account]; _remove(payeeArchive.addresses, account); payeeArchive.records[address(this)].shares -= recordToBeRemoved.shares; emit PayeeRemoved(account); } function getIndex(address[] memory list, address _address) private pure returns(uint256){ for (uint256 i = 0; i < list.length; i++) { if(list[i] == _address){ return i; } } // solhint-disable-next-line reason-string revert("PaymentSplitter: account not found"); } function _remove(address[] storage list, address account) private { _remove(list, getIndex(list, account)); } function _remove(address[] storage list, uint index) private { // Move the last element into the place to delete list[index] = list[list.length - 1]; // Remove the last element list.pop(); } /** * @dev Add a new payee to the contract. * @param account The address of the payee to add. * @param _shares The number of shares owned by the payee. */ function updatePayee(address account, uint256 _shares) public onlyOwner { _updatePayee(account, _shares); } /** * @dev Add a new payee to the contract. * @param account The address of the payee to add. * @param _shares The number of shares owned by the payee. */ function addPayee(address account, uint256 _shares) public onlyOwner { _addPayee(account, _shares); } /** * @dev Remove a payee from the contract. * @param account The address of the payee to remove. */ function removePayee(address account) public onlyOwner { _removePayee(account); } } // File contracts/YieldFarming.sol pragma solidity >=0.8.0 <0.9.0; contract YieldFarming is PaymentSplitter { using SafeERC20 for YieldFarmingToken; using SafeERC20 for IERC20; event YieldFarmingTokenBurn(address burner, uint amount); event YieldFarmingTokenRelease(address releaser, uint amount); Timestamp private timestamp; RewardCalculator immutable private rewardCalculator; YieldFarmingToken immutable public yieldFarmingToken; IERC20 immutable private acceptedToken; bytes16 private interestRate; bytes16 private multiplier; uint private lockTime; uint private tokenomicsTimestamp; mapping(address => TokenTimeLock[]) private tokenTimeLocks; constructor( Timestamp _timestamp, IERC20 _acceptedToken, RewardCalculator _rewardCalculator, string memory _tokenName, string memory _tokenSymbol, bytes16 _interestRate, bytes16 _multiplier, uint _lockTime, address[] memory _payees, uint256[] memory _shares ) PaymentSplitter(_acceptedToken, _payees, _shares) { timestamp = _timestamp; updateTokenomics(_interestRate, _multiplier, _lockTime); yieldFarmingToken = new YieldFarmingToken(_tokenName, _tokenSymbol); rewardCalculator = _rewardCalculator; acceptedToken = _acceptedToken; } function updateTokenomics(bytes16 _newInterestRate, bytes16 _newMultiplier, uint _newLockTime) public onlyOwner{ interestRate = _newInterestRate; multiplier = _newMultiplier; lockTime = _newLockTime; tokenomicsTimestamp = timestamp.getTimestamp(); } function deposit(uint amount) public { address depositor = _msgSender(); super.deposit(depositor, amount); uint timeStamp = timestamp.getTimestamp(); TokenTimeLock tokenTimeLock = new TokenTimeLock(timestamp, yieldFarmingToken, depositor, timeStamp + lockTime); tokenTimeLocks[depositor].push(tokenTimeLock); yieldFarmingToken.mint( address(tokenTimeLock), rewardCalculator.calculateQuantity(amount, multiplier, interestRate, timeStamp - tokenomicsTimestamp) ); } function burn(uint amount) public { address burner = _msgSender(); // // Original implementation: // yieldFarmingToken.safeTransferFrom(burner, address(this), amount); // yieldFarmingToken.safeIncreaseAllowance(address(this), amount); // yieldFarmingToken.burn(amount); // Optimized implementation: yieldFarmingToken.burnFrom(burner, amount); emit YieldFarmingTokenBurn(burner, amount); } function getMyTokenTimeLock(uint tokenTimelockIndex) public view returns (TokenTimeLock) { address me = _msgSender(); require(tokenTimelockIndex < tokenTimeLocks[me].length, "Index out of bounds!"); return tokenTimeLocks[me][tokenTimelockIndex]; } function getMyTokenTimeLocks() public view returns (TokenTimeLock[] memory) { return tokenTimeLocks[_msgSender()]; } function releaseTokens(uint tokenTimelockIndex) public { address releaser = _msgSender(); require(tokenTimelockIndex < tokenTimeLocks[releaser].length, "Index out of bounds!"); TokenTimeLock tokenTimelock = takeTokenTimeLock(releaser, tokenTimelockIndex); uint amount = yieldFarmingToken.balanceOf(address(tokenTimelock)); tokenTimelock.release(); emit YieldFarmingTokenRelease(releaser, amount); } function takeTokenTimeLock(address sender, uint tokenTimelockIndex) internal returns (TokenTimeLock) { TokenTimeLock element = tokenTimeLocks[sender][tokenTimelockIndex]; uint lengthM1 = tokenTimeLocks[sender].length - 1; tokenTimeLocks[sender][tokenTimelockIndex] = tokenTimeLocks[sender][lengthM1]; delete tokenTimeLocks[sender][lengthM1]; tokenTimeLocks[sender].pop; return element; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract Timestamp","name":"_timestamp","type":"address"},{"internalType":"contract IERC20","name":"_acceptedToken","type":"address"},{"internalType":"contract RewardCalculator","name":"_rewardCalculator","type":"address"},{"internalType":"string","name":"_tokenName","type":"string"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"bytes16","name":"_interestRate","type":"bytes16"},{"internalType":"bytes16","name":"_multiplier","type":"bytes16"},{"internalType":"uint256","name":"_lockTime","type":"uint256"},{"internalType":"address[]","name":"_payees","type":"address[]"},{"internalType":"uint256[]","name":"_shares","type":"uint256[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AcceptedTokenDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"PayeeRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"int256","name":"shares","type":"int256"}],"name":"PayeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"transferrer","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"sharesAmount","type":"uint256"}],"name":"SharesTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"burner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"YieldFarmingTokenBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"releaser","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"YieldFarmingTokenRelease","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"addPayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenTimelockIndex","type":"uint256"}],"name":"getMyTokenTimeLock","outputs":[{"internalType":"contract TokenTimeLock","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMyTokenTimeLocks","outputs":[{"internalType":"contract TokenTimeLock[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isPayee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"record","outputs":[{"components":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"released","type":"uint256"}],"internalType":"struct Record","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenTimelockIndex","type":"uint256"}],"name":"releaseTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removePayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"sharesAmount","type":"uint256"}],"name":"transferShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"updatePayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes16","name":"_newInterestRate","type":"bytes16"},{"internalType":"bytes16","name":"_newMultiplier","type":"bytes16"},{"internalType":"uint256","name":"_newLockTime","type":"uint256"}],"name":"updateTokenomics","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"yieldFarmingToken","outputs":[{"internalType":"contract YieldFarmingToken","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b5060405162004d3038038062004d308339810160408190526200003591620006ad565b8882826000620000446200020d565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508051825114620000bb5760405162461bcd60e51b8152600401620000b29062000927565b60405180910390fd5b6000825111620000df5760405162461bcd60e51b8152600401620000b29062000979565b60005b825181101562000163576200014e8382815181106200011157634e487b7160e01b600052603260045260246000fd5b60200260200101518383815181106200013a57634e487b7160e01b600052603260045260246000fd5b60200260200101516200021160201b60201c565b806200015a8162000a87565b915050620000e2565b50505060601b6001600160601b031916608052600380546001600160a01b0319166001600160a01b038c161790556200019e85858562000267565b8686604051620001ae906200050d565b620001bb9291906200082b565b604051809103906000f080158015620001d8573d6000803e3d6000fd5b506001600160601b0319606091821b811660c05298811b891660a0529890981b90961660e0525062000aea9650505050505050565b3390565b6200021b6200020d565b6001600160a01b03166200022e62000366565b6001600160a01b031614620002575760405162461bcd60e51b8152600401620000b290620008f2565b62000263828262000375565b5050565b620002716200020d565b6001600160a01b03166200028462000366565b6001600160a01b031614620002ad5760405162461bcd60e51b8152600401620000b290620008f2565b60048054608084811c600160801b029086901c6001600160801b0319909216919091176001600160801b0316178155600582905560035460408051630c4761ab60e11b815290516001600160a01b039092169263188ec356928282019260209290829003018186803b1580156200032357600080fd5b505afa15801562000338573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200035e9190620007cb565b600655505050565b6000546001600160a01b031690565b6001600160a01b0382166200039e5760405162461bcd60e51b8152600401620000b2906200085d565b60008111620003c15760405162461bcd60e51b8152600401620000b290620009b0565b620003cc82620004a5565b15620003ec5760405162461bcd60e51b8152600401620000b290620008a9565b6002805460018082019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b03851690811790915560009081526020919091526040808220839055308252812080548392906200046090849062000a39565b90915550506040517f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac9062000499908490849062000812565b60405180910390a15050565b600080620004b383620004bc565b1190505b919050565b6000620004c982620004d0565b5192915050565b620004da6200051b565b506001600160a01b0316600090815260016020818152604092839020835180850190945280548452909101549082015290565b6112ef8062003a4183390190565b604051806040016040528060008152602001600081525090565b600082601f83011262000546578081fd5b815160206200055f620005598362000a13565b620009e7565b82815281810190858301838502870184018810156200057c578586fd5b855b85811015620005a7578151620005948162000ad1565b845292840192908401906001016200057e565b5090979650505050505050565b600082601f830112620005c5578081fd5b81516020620005d8620005598362000a13565b8281528181019085830183850287018401881015620005f5578586fd5b855b85811015620005a757815184529284019290840190600101620005f7565b80516001600160801b031981168114620004b757600080fd5b8051620004b78162000ad1565b600082601f8301126200064c578081fd5b81516001600160401b0381111562000668576200066862000abb565b6200067d601f8201601f1916602001620009e7565b81815284602083860101111562000692578283fd5b620006a582602083016020870162000a54565b949350505050565b6000806000806000806000806000806101408b8d031215620006cd578586fd5b620006d88b6200062e565b9950620006e860208c016200062e565b9850620006f860408c016200062e565b60608c01519098506001600160401b038082111562000715578788fd5b620007238e838f016200063b565b985060808d015191508082111562000739578788fd5b620007478e838f016200063b565b97506200075760a08e0162000615565b96506200076760c08e0162000615565b955060e08d015194506101008d015191508082111562000785578384fd5b620007938e838f0162000535565b93506101208d0151915080821115620007aa578283fd5b50620007b98d828e01620005b4565b9150509295989b9194979a5092959850565b600060208284031215620007dd578081fd5b5051919050565b60008151808452620007fe81602086016020860162000a54565b601f01601f19169290920160200192915050565b6001600160a01b03929092168252602082015260400190565b600060408252620008406040830185620007e4565b8281036020840152620008548185620007e4565b95945050505050565b6020808252602c908201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060408201526b7a65726f206164647265737360a01b606082015260800190565b60208082526029908201527f5061796d656e7453706c69747465723a206163636f756e7420697320616c726560408201526861647920706179656560b81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526032908201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726040820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b606082015260800190565b6020808252601a908201527f5061796d656e7453706c69747465723a206e6f20706179656573000000000000604082015260600190565b6020808252601d908201527f5061796d656e7453706c69747465723a20736861726573206172652030000000604082015260600190565b6040518181016001600160401b038111828210171562000a0b5762000a0b62000abb565b604052919050565b60006001600160401b0382111562000a2f5762000a2f62000abb565b5060209081020190565b6000821982111562000a4f5762000a4f62000aa5565b500190565b60005b8381101562000a7157818101518382015260200162000a57565b8381111562000a81576000848401525b50505050565b600060001982141562000a9e5762000a9e62000aa5565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811462000ae757600080fd5b50565b60805160601c60a05160601c60c05160601c60e05160601c612eea62000b576000396000505060008181610765015281816108c001528181610a8a01528181610d550152610e0401526000610e300152600081816104130152818161057e015261160d0152612eea6000f3fe60806040523480156200001157600080fd5b5060043610620001605760003560e01c80635e36d0b211620000c95780639852595c11620000875780639852595c14620002ea578063b6b55f251462000301578063ce7c2ac21462000318578063e33b7de3146200032f578063efdc48f61462000339578063f2fde38b14620003505762000160565b80635e36d0b2146200029e578063715018a614620002a85780638b83209b14620002b25780638da5cb5b14620002c95780638fcb4e5b14620002d35762000160565b80633a98ef3911620001235780633a98ef3914620002105780633ed35855146200022957806342966c68146200024057806346ffdf9514620002575780634b0babdd146200026e578063506df12f14620002855762000160565b806318f9b023146200016557806319165587146200017e5780633407ef5314620001955780633465d6d514620001c4578063366653a914620001ea575b600080fd5b6200017c6200017636600462001aab565b62000367565b005b6200017c6200018f36600462001a8e565b620003c6565b620001ac620001a636600462001b39565b620005e6565b604051620001bb919062001b89565b60405180910390f35b620001db620001d536600462001a8e565b62000687565b604051620001bb919062002102565b62000201620001fb36600462001a8e565b620006c4565b604051620001bb919062001c29565b6200021a620006d9565b604051620001bb919062002119565b6200017c6200023a36600462001a8e565b620006eb565b6200017c6200025136600462001b39565b6200073f565b6200017c6200026836600462001aab565b62000811565b6200017c6200027f36600462001b39565b62000863565b6200028f620009f8565b604051620001bb919062001bda565b620001ac62000a88565b6200017c62000aac565b620001ac620002c336600462001b39565b62000b3c565b620001ac62000b7d565b6200017c620002e436600462001aab565b62000b8c565b6200021a620002fb36600462001a8e565b62000c89565b6200017c6200031236600462001b39565b62000ca0565b6200021a6200032936600462001a8e565b62000f45565b6200021a62000f59565b6200017c6200034a36600462001af9565b62000f66565b6200017c6200036136600462001a8e565b6200106e565b6200037162001138565b6001600160a01b03166200038462000b7d565b6001600160a01b031614620003b65760405162461bcd60e51b8152600401620003ad9062001fa6565b60405180910390fd5b620003c282826200113c565b5050565b620003d181620006c4565b620003f05760405162461bcd60e51b8152600401620003ad9062001cd5565b6000620003fc62000f59565b6040516370a0823160e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a08231906200044a90309060040162001b89565b60206040518083038186803b1580156200046357600080fd5b505afa15801562000478573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200049e919062001b52565b620004aa91906200218f565b90506000620004b98362000c89565b620004c3620006d9565b620004ce8562000f45565b620004da9085620021cb565b620004e69190620021aa565b620004f2919062002232565b905080620005145760405162461bcd60e51b8152600401620003ad9062001e87565b6001600160a01b03831660009081526001602081905260408220018054839290620005419084906200218f565b909155505030600090815260016020819052604082200180548392906200056a9084906200218f565b90915550620005a690506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016848362001260565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0568382604051620005d992919062001bc1565b60405180910390a1505050565b600080620005f362001138565b6001600160a01b0381166000908152600760205260409020549091508310620006305760405162461bcd60e51b8152600401620003ad906200209d565b6001600160a01b03811660009081526007602052604090208054849081106200066957634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03169150505b919050565b6200069162001a35565b506001600160a01b0316600090815260016020818152604092839020835180850190945280548452909101549082015290565b600080620006d28362000f45565b1192915050565b6000620006e63062000f45565b905090565b620006f562001138565b6001600160a01b03166200070862000b7d565b6001600160a01b031614620007315760405162461bcd60e51b8152600401620003ad9062001fa6565b6200073c81620012bf565b50565b60006200074b62001138565b60405163079cc67960e41b81529091506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379cc6790906200079e908490869060040162001bc1565b600060405180830381600087803b158015620007b957600080fd5b505af1158015620007ce573d6000803e3d6000fd5b505050507f5cb478659d0e1ed4c130006cb061387f6196e1153404d1e4ea0124aabe3798ac81836040516200080592919062001bc1565b60405180910390a15050565b6200081b62001138565b6001600160a01b03166200082e62000b7d565b6001600160a01b031614620008575760405162461bcd60e51b8152600401620003ad9062001fa6565b620003c2828262001376565b60006200086f62001138565b6001600160a01b0381166000908152600760205260409020549091508210620008ac5760405162461bcd60e51b8152600401620003ad906200209d565b6000620008ba828462001476565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231836040518263ffffffff1660e01b81526004016200090c919062001b89565b60206040518083038186803b1580156200092557600080fd5b505afa1580156200093a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000960919062001b52565b9050816001600160a01b03166386d1a69f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200099e57600080fd5b505af1158015620009b3573d6000803e3d6000fd5b505050507fc171a40b932e975803a0d30e6180781ee556ed7615553185347606a918764ca18382604051620009ea92919062001bc1565b60405180910390a150505050565b60606007600062000a0862001138565b6001600160a01b03166001600160a01b0316815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801562000a7e57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000a5f575b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b62000ab662001138565b6001600160a01b031662000ac962000b7d565b6001600160a01b03161462000af25760405162461bcd60e51b8152600401620003ad9062001fa6565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600060018001828154811062000b6257634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031692915050565b6000546001600160a01b031690565b600062000b9862001138565b905062000ba581620006c4565b62000bc45760405162461bcd60e51b8152600401620003ad9062001ed2565b8162000bd08262000f45565b101562000bf15760405162461bcd60e51b8152600401620003ad9062001d1c565b62000c14818362000c028462000f45565b62000c0e919062002232565b62001376565b62000c1f83620006c4565b1562000c485762000c42838362000c368662000f45565b62000c0e91906200218f565b62000c54565b62000c5483836200113c565b7f99c01cd4f8275976ef33d24514b1694c8a9d5730d92e26996834343e09778e99818484604051620005d99392919062001b9d565b600062000c968262000687565b6020015192915050565b600062000cac62001138565b905062000cba8183620015ff565b60035460408051630c4761ab60e11b815290516000926001600160a01b03169163188ec356916004808301926020929190829003018186803b15801562000d0057600080fd5b505afa15801562000d15573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d3b919062001b52565b6003546005549192506000916001600160a01b03909116907f000000000000000000000000000000000000000000000000000000000000000090859062000d8390866200218f565b60405162000d919062001a4f565b62000da0949392919062001c34565b604051809103906000f08015801562000dbd573d6000803e3d6000fd5b506001600160a01b0384811660009081526007602090815260408220805460018101825590835291200180546001600160a01b0319168383161790556004546006549293507f00000000000000000000000000000000000000000000000000000000000000008216926340c10f199285927f000000000000000000000000000000000000000000000000000000000000000090911691639868a60c918a91600160801b8204608090811b92901b9062000e77908b62002232565b6040518563ffffffff1660e01b815260040162000e98949392919062002122565b60206040518083038186803b15801562000eb157600080fd5b505afa15801562000ec6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000eec919062001b52565b6040518363ffffffff1660e01b815260040162000f0b92919062001bc1565b600060405180830381600087803b15801562000f2657600080fd5b505af115801562000f3b573d6000803e3d6000fd5b5050505050505050565b600062000f528262000687565b5192915050565b6000620006e63062000c89565b62000f7062001138565b6001600160a01b031662000f8362000b7d565b6001600160a01b03161462000fac5760405162461bcd60e51b8152600401620003ad9062001fa6565b60048054608084811c600160801b029086901c6001600160801b0319909216919091176fffffffffffffffffffffffffffffffff16178155600582905560035460408051630c4761ab60e11b815290516001600160a01b039092169263188ec356928282019260209290829003018186803b1580156200102b57600080fd5b505afa15801562001040573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001066919062001b52565b600655505050565b6200107862001138565b6001600160a01b03166200108b62000b7d565b6001600160a01b031614620010b45760405162461bcd60e51b8152600401620003ad9062001fa6565b6001600160a01b038116620010dd5760405162461bcd60e51b8152600401620003ad9062001db2565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b038216620011655760405162461bcd60e51b8152600401620003ad9062001d66565b60008111620011885760405162461bcd60e51b8152600401620003ad90620020cb565b6200119382620006c4565b15620011b35760405162461bcd60e51b8152600401620003ad9062001df8565b6002805460018082019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b0385169081179091556000908152602091909152604080822083905530825281208054839290620012279084906200218f565b90915550506040517f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac9062000805908490849062001bc1565b620012ba8363a9059cbb60e01b84846040516024016200128292919062001bc1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262001669565b505050565b600254620012e15760405162461bcd60e51b8152600401620003ad9062001fdb565b6000620012ee8262000687565b6001600160a01b03831660009081526001602081905260408220828155015590506200131c60028362001700565b805130600090815260016020526040812080549091906200133f90849062002232565b90915550506040517fc2ee819acfe1baf117c2aac9d3f627a864f075d2fecc990eebd82d59f2662605906200080590849062001b89565b6200138182620006c4565b620013a05760405162461bcd60e51b8152600401620003ad9062001f6f565b80620013b757620013b182620012bf565b620003c2565b80620013c38362000f45565b1415620013e45760405162461bcd60e51b8152600401620003ad9062001f1a565b6000620013f18362000f45565b620013fd9083620021ed565b6001600160a01b0384166000908152600160205260408082208590553082529020549091506200142f90829062002148565b306000908152600160205260409081902091909155517fb309421c365a9d0a93013157ebb019e68b808bab098cce6a7bdec150a6857a4390620005d9908590849062001bc1565b6001600160a01b0382166000908152600760205260408120805482919084908110620014b257634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0387811684526007909252604083205491169250620014e99060019062002232565b6001600160a01b0386166000908152600760205260409020805491925090829081106200152657634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b038881168452600790925260409092208054919092169190869081106200157257634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559187168152600790915260409020805482908110620015c957634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910180546001600160a01b03191690556001600160a01b038716909152600790525090505b92915050565b620016366001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001683308462001772565b7f95dabc2c18727d8869745ab20c77624af79f7b1376130fb395fcb46c22274db982826040516200080592919062001bc1565b6000620016c0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200179c9092919063ffffffff16565b805190915015620012ba5780806020019051810190620016e1919062001ad7565b620012ba5760405162461bcd60e51b8152600401620003ad9062002053565b620003c2826200176c848054806020026020016040519081016040528092919081815260200182805480156200176057602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001741575b505050505084620017b7565b62001840565b62001796846323b872dd60e01b858585604051602401620012829392919062001b9d565b50505050565b6060620017ad848460008562001923565b90505b9392505050565b6000805b83518110156200182557826001600160a01b0316848281518110620017f057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141562001810579050620015f9565b806200181c816200227b565b915050620017bb565b5060405162461bcd60e51b8152600401620003ad9062001c93565b81548290620018529060019062002232565b815481106200187157634e487b7160e01b600052603260045260246000fd5b9060005260206000200160009054906101000a90046001600160a01b0316828281548110620018b057634e487b7160e01b600052603260045260246000fd5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081805480620018fd57634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b03191690550190555050565b606082471015620019485760405162461bcd60e51b8152600401620003ad9062001e41565b6200195385620019f1565b620019725760405162461bcd60e51b8152600401620003ad906200201c565b600080866001600160a01b0316858760405162001990919062001b6b565b60006040518083038185875af1925050503d8060008114620019cf576040519150601f19603f3d011682016040523d82523d6000602084013e620019d4565b606091505b5091509150620019e6828286620019f7565b979650505050505050565b3b151590565b6060831562001a08575081620017b0565b82511562001a195782518084602001fd5b8160405162461bcd60e51b8152600401620003ad919062001c5e565b604051806040016040528060008152602001600081525090565b610c0580620022b083390190565b80356001600160a01b03811681146200068257600080fd5b80356001600160801b0319811681146200068257600080fd5b60006020828403121562001aa0578081fd5b620017b08262001a5d565b6000806040838503121562001abe578081fd5b62001ac98362001a5d565b946020939093013593505050565b60006020828403121562001ae9578081fd5b81518015158114620017b0578182fd5b60008060006060848603121562001b0e578081fd5b62001b198462001a75565b925062001b296020850162001a75565b9150604084013590509250925092565b60006020828403121562001b4b578081fd5b5035919050565b60006020828403121562001b64578081fd5b5051919050565b6000825162001b7f8184602087016200224c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101562001c1d5783516001600160a01b03168352928401929184019160010162001bf6565b50909695505050505050565b901515815260200190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b600060208252825180602084015262001c7f8160408501602087016200224c565b601f01601f19169190910160400192915050565b60208082526022908201527f5061796d656e7453706c69747465723a206163636f756e74206e6f7420666f756040820152611b9960f21b606082015260800190565b60208082526027908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f74206040820152666120706179656560c81b606082015260800190565b6020808252602a908201527f5061796d656e7453706c69747465723a206e6f7420656e6f756768207368617260408201526965732062616c616e636560b01b606082015260800190565b6020808252602c908201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060408201526b7a65726f206164647265737360a01b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526029908201527f5061796d656e7453706c69747465723a206163636f756e7420697320616c726560408201526861647920706179656560b81b606082015260800190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b60208082526028908201527f5061796d656e7453706c69747465723a207472616e73666572726572206e6f74604082015267206120706179656560c01b606082015260800190565b60208082526035908201527f5061796d656e7453706c69747465723a206163636f756e7420616c7265616479604082015274206861732074686174206d616e792073686172657360581b606082015260800190565b6020808252601c908201527f5061796d656e7453706c69747465723a206e6f74206120706179656500000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526021908201527f5061796d656e7453706c69747465723a20656d707479207061796565206c69736040820152601d60fa1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b602080825260149082015273496e646578206f7574206f6620626f756e64732160601b604082015260600190565b6020808252601d908201527f5061796d656e7453706c69747465723a20736861726573206172652030000000604082015260600190565b815181526020918201519181019190915260400190565b90815260200190565b9384526001600160801b0319928316602085015291166040830152606082015260800190565b600080821280156001600160ff1b03849003851316156200216d576200216d62002299565b600160ff1b839003841281161562002189576200218962002299565b50500190565b60008219821115620021a557620021a562002299565b500190565b600082620021c657634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615620021e857620021e862002299565b500290565b60008083128015600160ff1b8501841216156200220e576200220e62002299565b6001600160ff1b03840183138116156200222c576200222c62002299565b50500390565b60008282101562002247576200224762002299565b500390565b60005b83811015620022695781810151838201526020016200224f565b83811115620017965750506000910152565b600060001982141562002292576200229262002299565b5060010190565b634e487b7160e01b600052601160045260246000fdfe60e060405234801561001057600080fd5b50604051610c05380380610c0583398101604081905261002f91610166565b6000610039610162565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b0319166001600160a01b03868116919091179182905560408051630c4761ab60e11b81529051929091169163188ec35691600480820192602092909190829003018186803b1580156100df57600080fd5b505afa1580156100f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061011791906101b8565b811161013e5760405162461bcd60e51b8152600401610135906101d0565b60405180910390fd5b6001600160601b0319606093841b81166080529190921b1660a05260c0525061023a565b3390565b6000806000806080858703121561017b578384fd5b845161018681610222565b602086015190945061019781610222565b60408601519093506101a881610222565b6060959095015193969295505050565b6000602082840312156101c9578081fd5b5051919050565b60208082526032908201527f546f6b656e54696d654c6f636b3a2072656c656173652074696d65206973206260408201527165666f72652063757272656e742074696d6560701b606082015260800190565b6001600160a01b038116811461023757600080fd5b50565b60805160601c60a05160601c60c05161099761026e600039600061036a0152600060ec0152600061044e01526109976000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100b2578063b91d4001146100ba578063f2fde38b146100cf578063fc0c546a146100e25761007d565b806338af3eed14610082578063715018a6146100a057806386d1a69f146100aa575b600080fd5b61008a6100ea565b60405161009791906106f1565b60405180910390f35b6100a861010e565b005b6100a86101a0565b61008a610359565b6100c2610368565b6040516100979190610928565b6100a86100dd366004610676565b61038c565b61008a61044c565b7f000000000000000000000000000000000000000000000000000000000000000090565b610116610470565b6001600160a01b0316610127610359565b6001600160a01b0316146101565760405162461bcd60e51b815260040161014d90610872565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6101a8610470565b6001600160a01b03166101b9610359565b6001600160a01b0316146101df5760405162461bcd60e51b815260040161014d90610872565b6101e7610368565b600160009054906101000a90046001600160a01b03166001600160a01b031663188ec3566040518163ffffffff1660e01b815260040160206040518083038186803b15801561023557600080fd5b505afa158015610249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026d91906106bd565b101561028b5760405162461bcd60e51b815260040161014d90610820565b600061029561044c565b6001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016102c091906106f1565b60206040518083038186803b1580156102d857600080fd5b505afa1580156102ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031091906106bd565b9050600081116103325760405162461bcd60e51b815260040161014d90610797565b61035661033d6100ea565b8261034661044c565b6001600160a01b03169190610474565b50565b6000546001600160a01b031690565b7f000000000000000000000000000000000000000000000000000000000000000090565b610394610470565b6001600160a01b03166103a5610359565b6001600160a01b0316146103cb5760405162461bcd60e51b815260040161014d90610872565b6001600160a01b0381166103f15760405162461bcd60e51b815260040161014d90610751565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b7f000000000000000000000000000000000000000000000000000000000000000090565b3390565b6104ca8363a9059cbb60e01b8484604051602401610493929190610705565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526104cf565b505050565b6000610524826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661055e9092919063ffffffff16565b8051909150156104ca5780806020019051810190610542919061069d565b6104ca5760405162461bcd60e51b815260040161014d906108de565b606061056d8484600085610577565b90505b9392505050565b6060824710156105995760405162461bcd60e51b815260040161014d906107da565b6105a285610637565b6105be5760405162461bcd60e51b815260040161014d906108a7565b600080866001600160a01b031685876040516105da91906106d5565b60006040518083038185875af1925050503d8060008114610617576040519150601f19603f3d011682016040523d82523d6000602084013e61061c565b606091505b509150915061062c82828661063d565b979650505050505050565b3b151590565b6060831561064c575081610570565b82511561065c5782518084602001fd5b8160405162461bcd60e51b815260040161014d919061071e565b600060208284031215610687578081fd5b81356001600160a01b0381168114610570578182fd5b6000602082840312156106ae578081fd5b81518015158114610570578182fd5b6000602082840312156106ce578081fd5b5051919050565b600082516106e7818460208701610931565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b600060208252825180602084015261073d816040850160208701610931565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526023908201527f546f6b656e54696d654c6f636b3a206e6f20746f6b656e7320746f2072656c6560408201526261736560e81b606082015260800190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b60208082526032908201527f546f6b656e54696d654c6f636b3a2063757272656e742074696d65206973206260408201527165666f72652072656c656173652074696d6560701b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561094c578181015183820152602001610934565b8381111561095b576000848401525b5050505056fea26469706673582212201b2f059ff1f30db8b1ff5ab400f78c02543013e6e5f989a11129d6216fd72d4f64736f6c63430008000033a26469706673582212204de049cb9cef9bd9825dfb77577b0d16ae2aa00a8cca74cec4c51a9d7316c11264736f6c6343000800003360806040523480156200001157600080fd5b50604051620012ef380380620012ef833981016040819052620000349162000223565b8151829082906200004d906003906020850190620000d2565b50805162000063906004906020840190620000d2565b505050600062000078620000ce60201b60201c565b600580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505050620002dd565b3390565b828054620000e0906200028a565b90600052602060002090601f0160209004810192826200010457600085556200014f565b82601f106200011f57805160ff19168380011785556200014f565b828001600101855582156200014f579182015b828111156200014f57825182559160200191906001019062000132565b506200015d92915062000161565b5090565b5b808211156200015d576000815560010162000162565b600082601f83011262000189578081fd5b81516001600160401b0380821115620001a657620001a6620002c7565b6040516020601f8401601f1916820181018381118382101715620001ce57620001ce620002c7565b6040528382528584018101871015620001e5578485fd5b8492505b83831015620002085785830181015182840182015291820191620001e9565b838311156200021957848185840101525b5095945050505050565b6000806040838503121562000236578182fd5b82516001600160401b03808211156200024d578384fd5b6200025b8683870162000178565b9350602085015191508082111562000271578283fd5b50620002808582860162000178565b9150509250929050565b6002810460018216806200029f57607f821691505b60208210811415620002c157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b61100280620002ed6000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806370a08231116100a257806395d89b411161007157806395d89b4114610209578063a457c2d714610211578063a9059cbb14610224578063dd62ed3e14610237578063f2fde38b1461024a5761010b565b806370a08231146101c6578063715018a6146101d957806379cc6790146101e15780638da5cb5b146101f45761010b565b8063313ce567116100de578063313ce56714610176578063395093511461018b57806340c10f191461019e57806342966c68146101b35761010b565b806306fdde0314610110578063095ea7b31461012e57806318160ddd1461014e57806323b872dd14610163575b600080fd5b61011861025d565b6040516101259190610b88565b60405180910390f35b61014161013c366004610b28565b6102ef565b6040516101259190610b7d565b61015661030c565b6040516101259190610f35565b610141610171366004610aed565b610312565b61017e6103b2565b6040516101259190610f3e565b610141610199366004610b28565b6103b7565b6101b16101ac366004610b28565b610406565b005b6101b16101c1366004610b51565b610453565b6101566101d4366004610a9a565b610467565b6101b1610486565b6101b16101ef366004610b28565b61050f565b6101fc610564565b6040516101259190610b69565b610118610573565b61014161021f366004610b28565b610582565b610141610232366004610b28565b6105fd565b610156610245366004610abb565b610611565b6101b1610258366004610a9a565b61063c565b60606003805461026c90610f7b565b80601f016020809104026020016040519081016040528092919081815260200182805461029890610f7b565b80156102e55780601f106102ba576101008083540402835291602001916102e5565b820191906000526020600020905b8154815290600101906020018083116102c857829003601f168201915b5050505050905090565b60006103036102fc6106fd565b8484610701565b50600192915050565b60025490565b600061031f8484846107b5565b6001600160a01b0384166000908152600160205260408120816103406106fd565b6001600160a01b03166001600160a01b031681526020019081526020016000205490508281101561038c5760405162461bcd60e51b815260040161038390610d2e565b60405180910390fd5b6103a7856103986106fd565b6103a28685610f64565b610701565b506001949350505050565b601290565b60006103036103c46106fd565b8484600160006103d26106fd565b6001600160a01b03908116825260208083019390935260409182016000908120918b16815292529020546103a29190610f4c565b61040e6106fd565b6001600160a01b031661041f610564565b6001600160a01b0316146104455760405162461bcd60e51b815260040161038390610d76565b61044f82826108dd565b5050565b61046461045e6106fd565b8261099d565b50565b6001600160a01b0381166000908152602081905260409020545b919050565b61048e6106fd565b6001600160a01b031661049f610564565b6001600160a01b0316146104c55760405162461bcd60e51b815260040161038390610d76565b6005546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580546001600160a01b0319169055565b600061051d836102456106fd565b90508181101561053f5760405162461bcd60e51b815260040161038390610dab565b6105558361054b6106fd565b6103a28585610f64565b61055f838361099d565b505050565b6005546001600160a01b031690565b60606004805461026c90610f7b565b600080600160006105916106fd565b6001600160a01b03908116825260208083019390935260409182016000908120918816815292529020549050828110156105dd5760405162461bcd60e51b815260040161038390610eb9565b6105f36105e86106fd565b856103a28685610f64565b5060019392505050565b600061030361060a6106fd565b84846107b5565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6106446106fd565b6001600160a01b0316610655610564565b6001600160a01b03161461067b5760405162461bcd60e51b815260040161038390610d76565b6001600160a01b0381166106a15760405162461bcd60e51b815260040161038390610c60565b6005546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b0383166107275760405162461bcd60e51b815260040161038390610e75565b6001600160a01b03821661074d5760405162461bcd60e51b815260040161038390610ca6565b6001600160a01b0380841660008181526001602090815260408083209487168084529490915290819020849055517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906107a8908590610f35565b60405180910390a3505050565b6001600160a01b0383166107db5760405162461bcd60e51b815260040161038390610e30565b6001600160a01b0382166108015760405162461bcd60e51b815260040161038390610bdb565b61080c83838361055f565b6001600160a01b038316600090815260208190526040902054818110156108455760405162461bcd60e51b815260040161038390610ce8565b61084f8282610f64565b6001600160a01b038086166000908152602081905260408082209390935590851681529081208054849290610885908490610f4c565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516108cf9190610f35565b60405180910390a350505050565b6001600160a01b0382166109035760405162461bcd60e51b815260040161038390610efe565b61090f6000838361055f565b80600260008282546109219190610f4c565b90915550506001600160a01b0382166000908152602081905260408120805483929061094e908490610f4c565b90915550506040516001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610991908590610f35565b60405180910390a35050565b6001600160a01b0382166109c35760405162461bcd60e51b815260040161038390610def565b6109cf8260008361055f565b6001600160a01b03821660009081526020819052604090205481811015610a085760405162461bcd60e51b815260040161038390610c1e565b610a128282610f64565b6001600160a01b03841660009081526020819052604081209190915560028054849290610a40908490610f64565b90915550506040516000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107a8908690610f35565b80356001600160a01b038116811461048157600080fd5b600060208284031215610aab578081fd5b610ab482610a83565b9392505050565b60008060408385031215610acd578081fd5b610ad683610a83565b9150610ae460208401610a83565b90509250929050565b600080600060608486031215610b01578081fd5b610b0a84610a83565b9250610b1860208501610a83565b9150604084013590509250925092565b60008060408385031215610b3a578182fd5b610b4383610a83565b946020939093013593505050565b600060208284031215610b62578081fd5b5035919050565b6001600160a01b0391909116815260200190565b901515815260200190565b6000602080835283518082850152825b81811015610bb457858101830151858201604001528201610b98565b81811115610bc55783604083870101525b50601f01601f1916929092016040019392505050565b60208082526023908201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260408201526265737360e81b606082015260800190565b60208082526022908201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604082015261636560f01b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526022908201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604082015261737360f01b606082015260800190565b60208082526026908201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604082015265616c616e636560d01b606082015260800190565b60208082526028908201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616040820152676c6c6f77616e636560c01b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526024908201527f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f77604082015263616e636560e01b606082015260800190565b60208082526021908201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526025908201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604082015264647265737360d81b606082015260800190565b60208082526024908201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526025908201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604082015264207a65726f60d81b606082015260800190565b6020808252601f908201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604082015260600190565b90815260200190565b60ff91909116815260200190565b60008219821115610f5f57610f5f610fb6565b500190565b600082821015610f7657610f76610fb6565b500390565b600281046001821680610f8f57607f821691505b60208210811415610fb057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220dfcd22be314ee4e2f82a9ff983f1140f0667cd60bd850012541174bc185606bb64736f6c63430008000033000000000000000000000000227de4453a8840cd62e0d4336dc75b72ff89e5ce0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa8417400000000000000000000000076c1217105d2aa63d64367323091873f9754b563000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001803ff647ae147ae147ae147ae147ae147a000000000000000000000000000000004026d1a94a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000001a496e74657265737420466173746572205468616e204c6967687400000000000000000000000000000000000000000000000000000000000000000000000000044946544c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000028e19c0f68d34313320b10ba538299dc78f4192c000000000000000000000000150c1a134941cab797c1fca4f33ec1246076c578000000000000000000000000c0320245f52c1a9b7d6d22e07b1ffaae56afa5680000000000000000000000007826833c65a4a99310175140a447eb60ef2969360000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000032
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620001605760003560e01c80635e36d0b211620000c95780639852595c11620000875780639852595c14620002ea578063b6b55f251462000301578063ce7c2ac21462000318578063e33b7de3146200032f578063efdc48f61462000339578063f2fde38b14620003505762000160565b80635e36d0b2146200029e578063715018a614620002a85780638b83209b14620002b25780638da5cb5b14620002c95780638fcb4e5b14620002d35762000160565b80633a98ef3911620001235780633a98ef3914620002105780633ed35855146200022957806342966c68146200024057806346ffdf9514620002575780634b0babdd146200026e578063506df12f14620002855762000160565b806318f9b023146200016557806319165587146200017e5780633407ef5314620001955780633465d6d514620001c4578063366653a914620001ea575b600080fd5b6200017c6200017636600462001aab565b62000367565b005b6200017c6200018f36600462001a8e565b620003c6565b620001ac620001a636600462001b39565b620005e6565b604051620001bb919062001b89565b60405180910390f35b620001db620001d536600462001a8e565b62000687565b604051620001bb919062002102565b62000201620001fb36600462001a8e565b620006c4565b604051620001bb919062001c29565b6200021a620006d9565b604051620001bb919062002119565b6200017c6200023a36600462001a8e565b620006eb565b6200017c6200025136600462001b39565b6200073f565b6200017c6200026836600462001aab565b62000811565b6200017c6200027f36600462001b39565b62000863565b6200028f620009f8565b604051620001bb919062001bda565b620001ac62000a88565b6200017c62000aac565b620001ac620002c336600462001b39565b62000b3c565b620001ac62000b7d565b6200017c620002e436600462001aab565b62000b8c565b6200021a620002fb36600462001a8e565b62000c89565b6200017c6200031236600462001b39565b62000ca0565b6200021a6200032936600462001a8e565b62000f45565b6200021a62000f59565b6200017c6200034a36600462001af9565b62000f66565b6200017c6200036136600462001a8e565b6200106e565b6200037162001138565b6001600160a01b03166200038462000b7d565b6001600160a01b031614620003b65760405162461bcd60e51b8152600401620003ad9062001fa6565b60405180910390fd5b620003c282826200113c565b5050565b620003d181620006c4565b620003f05760405162461bcd60e51b8152600401620003ad9062001cd5565b6000620003fc62000f59565b6040516370a0823160e01b81526001600160a01b037f0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa8417416906370a08231906200044a90309060040162001b89565b60206040518083038186803b1580156200046357600080fd5b505afa15801562000478573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200049e919062001b52565b620004aa91906200218f565b90506000620004b98362000c89565b620004c3620006d9565b620004ce8562000f45565b620004da9085620021cb565b620004e69190620021aa565b620004f2919062002232565b905080620005145760405162461bcd60e51b8152600401620003ad9062001e87565b6001600160a01b03831660009081526001602081905260408220018054839290620005419084906200218f565b909155505030600090815260016020819052604082200180548392906200056a9084906200218f565b90915550620005a690506001600160a01b037f0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa8417416848362001260565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b0568382604051620005d992919062001bc1565b60405180910390a1505050565b600080620005f362001138565b6001600160a01b0381166000908152600760205260409020549091508310620006305760405162461bcd60e51b8152600401620003ad906200209d565b6001600160a01b03811660009081526007602052604090208054849081106200066957634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03169150505b919050565b6200069162001a35565b506001600160a01b0316600090815260016020818152604092839020835180850190945280548452909101549082015290565b600080620006d28362000f45565b1192915050565b6000620006e63062000f45565b905090565b620006f562001138565b6001600160a01b03166200070862000b7d565b6001600160a01b031614620007315760405162461bcd60e51b8152600401620003ad9062001fa6565b6200073c81620012bf565b50565b60006200074b62001138565b60405163079cc67960e41b81529091506001600160a01b037f0000000000000000000000001a69c53ff96b103e46ed2178b8d6098f59b2912516906379cc6790906200079e908490869060040162001bc1565b600060405180830381600087803b158015620007b957600080fd5b505af1158015620007ce573d6000803e3d6000fd5b505050507f5cb478659d0e1ed4c130006cb061387f6196e1153404d1e4ea0124aabe3798ac81836040516200080592919062001bc1565b60405180910390a15050565b6200081b62001138565b6001600160a01b03166200082e62000b7d565b6001600160a01b031614620008575760405162461bcd60e51b8152600401620003ad9062001fa6565b620003c2828262001376565b60006200086f62001138565b6001600160a01b0381166000908152600760205260409020549091508210620008ac5760405162461bcd60e51b8152600401620003ad906200209d565b6000620008ba828462001476565b905060007f0000000000000000000000001a69c53ff96b103e46ed2178b8d6098f59b291256001600160a01b03166370a08231836040518263ffffffff1660e01b81526004016200090c919062001b89565b60206040518083038186803b1580156200092557600080fd5b505afa1580156200093a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000960919062001b52565b9050816001600160a01b03166386d1a69f6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156200099e57600080fd5b505af1158015620009b3573d6000803e3d6000fd5b505050507fc171a40b932e975803a0d30e6180781ee556ed7615553185347606a918764ca18382604051620009ea92919062001bc1565b60405180910390a150505050565b60606007600062000a0862001138565b6001600160a01b03166001600160a01b0316815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801562000a7e57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000a5f575b5050505050905090565b7f0000000000000000000000001a69c53ff96b103e46ed2178b8d6098f59b2912581565b62000ab662001138565b6001600160a01b031662000ac962000b7d565b6001600160a01b03161462000af25760405162461bcd60e51b8152600401620003ad9062001fa6565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600060018001828154811062000b6257634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b031692915050565b6000546001600160a01b031690565b600062000b9862001138565b905062000ba581620006c4565b62000bc45760405162461bcd60e51b8152600401620003ad9062001ed2565b8162000bd08262000f45565b101562000bf15760405162461bcd60e51b8152600401620003ad9062001d1c565b62000c14818362000c028462000f45565b62000c0e919062002232565b62001376565b62000c1f83620006c4565b1562000c485762000c42838362000c368662000f45565b62000c0e91906200218f565b62000c54565b62000c5483836200113c565b7f99c01cd4f8275976ef33d24514b1694c8a9d5730d92e26996834343e09778e99818484604051620005d99392919062001b9d565b600062000c968262000687565b6020015192915050565b600062000cac62001138565b905062000cba8183620015ff565b60035460408051630c4761ab60e11b815290516000926001600160a01b03169163188ec356916004808301926020929190829003018186803b15801562000d0057600080fd5b505afa15801562000d15573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d3b919062001b52565b6003546005549192506000916001600160a01b03909116907f0000000000000000000000001a69c53ff96b103e46ed2178b8d6098f59b2912590859062000d8390866200218f565b60405162000d919062001a4f565b62000da0949392919062001c34565b604051809103906000f08015801562000dbd573d6000803e3d6000fd5b506001600160a01b0384811660009081526007602090815260408220805460018101825590835291200180546001600160a01b0319168383161790556004546006549293507f0000000000000000000000001a69c53ff96b103e46ed2178b8d6098f59b291258216926340c10f199285927f00000000000000000000000076c1217105d2aa63d64367323091873f9754b56390911691639868a60c918a91600160801b8204608090811b92901b9062000e77908b62002232565b6040518563ffffffff1660e01b815260040162000e98949392919062002122565b60206040518083038186803b15801562000eb157600080fd5b505afa15801562000ec6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000eec919062001b52565b6040518363ffffffff1660e01b815260040162000f0b92919062001bc1565b600060405180830381600087803b15801562000f2657600080fd5b505af115801562000f3b573d6000803e3d6000fd5b5050505050505050565b600062000f528262000687565b5192915050565b6000620006e63062000c89565b62000f7062001138565b6001600160a01b031662000f8362000b7d565b6001600160a01b03161462000fac5760405162461bcd60e51b8152600401620003ad9062001fa6565b60048054608084811c600160801b029086901c6001600160801b0319909216919091176fffffffffffffffffffffffffffffffff16178155600582905560035460408051630c4761ab60e11b815290516001600160a01b039092169263188ec356928282019260209290829003018186803b1580156200102b57600080fd5b505afa15801562001040573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001066919062001b52565b600655505050565b6200107862001138565b6001600160a01b03166200108b62000b7d565b6001600160a01b031614620010b45760405162461bcd60e51b8152600401620003ad9062001fa6565b6001600160a01b038116620010dd5760405162461bcd60e51b8152600401620003ad9062001db2565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b6001600160a01b038216620011655760405162461bcd60e51b8152600401620003ad9062001d66565b60008111620011885760405162461bcd60e51b8152600401620003ad90620020cb565b6200119382620006c4565b15620011b35760405162461bcd60e51b8152600401620003ad9062001df8565b6002805460018082019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b0385169081179091556000908152602091909152604080822083905530825281208054839290620012279084906200218f565b90915550506040517f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac9062000805908490849062001bc1565b620012ba8363a9059cbb60e01b84846040516024016200128292919062001bc1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262001669565b505050565b600254620012e15760405162461bcd60e51b8152600401620003ad9062001fdb565b6000620012ee8262000687565b6001600160a01b03831660009081526001602081905260408220828155015590506200131c60028362001700565b805130600090815260016020526040812080549091906200133f90849062002232565b90915550506040517fc2ee819acfe1baf117c2aac9d3f627a864f075d2fecc990eebd82d59f2662605906200080590849062001b89565b6200138182620006c4565b620013a05760405162461bcd60e51b8152600401620003ad9062001f6f565b80620013b757620013b182620012bf565b620003c2565b80620013c38362000f45565b1415620013e45760405162461bcd60e51b8152600401620003ad9062001f1a565b6000620013f18362000f45565b620013fd9083620021ed565b6001600160a01b0384166000908152600160205260408082208590553082529020549091506200142f90829062002148565b306000908152600160205260409081902091909155517fb309421c365a9d0a93013157ebb019e68b808bab098cce6a7bdec150a6857a4390620005d9908590849062001bc1565b6001600160a01b0382166000908152600760205260408120805482919084908110620014b257634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b0387811684526007909252604083205491169250620014e99060019062002232565b6001600160a01b0386166000908152600760205260409020805491925090829081106200152657634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b038881168452600790925260409092208054919092169190869081106200157257634e487b7160e01b600052603260045260246000fd5b600091825260208083209190910180546001600160a01b0319166001600160a01b039485161790559187168152600790915260409020805482908110620015c957634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910180546001600160a01b03191690556001600160a01b038716909152600790525090505b92915050565b620016366001600160a01b037f0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa841741683308462001772565b7f95dabc2c18727d8869745ab20c77624af79f7b1376130fb395fcb46c22274db982826040516200080592919062001bc1565b6000620016c0826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200179c9092919063ffffffff16565b805190915015620012ba5780806020019051810190620016e1919062001ad7565b620012ba5760405162461bcd60e51b8152600401620003ad9062002053565b620003c2826200176c848054806020026020016040519081016040528092919081815260200182805480156200176057602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162001741575b505050505084620017b7565b62001840565b62001796846323b872dd60e01b858585604051602401620012829392919062001b9d565b50505050565b6060620017ad848460008562001923565b90505b9392505050565b6000805b83518110156200182557826001600160a01b0316848281518110620017f057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141562001810579050620015f9565b806200181c816200227b565b915050620017bb565b5060405162461bcd60e51b8152600401620003ad9062001c93565b81548290620018529060019062002232565b815481106200187157634e487b7160e01b600052603260045260246000fd5b9060005260206000200160009054906101000a90046001600160a01b0316828281548110620018b057634e487b7160e01b600052603260045260246000fd5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081805480620018fd57634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b03191690550190555050565b606082471015620019485760405162461bcd60e51b8152600401620003ad9062001e41565b6200195385620019f1565b620019725760405162461bcd60e51b8152600401620003ad906200201c565b600080866001600160a01b0316858760405162001990919062001b6b565b60006040518083038185875af1925050503d8060008114620019cf576040519150601f19603f3d011682016040523d82523d6000602084013e620019d4565b606091505b5091509150620019e6828286620019f7565b979650505050505050565b3b151590565b6060831562001a08575081620017b0565b82511562001a195782518084602001fd5b8160405162461bcd60e51b8152600401620003ad919062001c5e565b604051806040016040528060008152602001600081525090565b610c0580620022b083390190565b80356001600160a01b03811681146200068257600080fd5b80356001600160801b0319811681146200068257600080fd5b60006020828403121562001aa0578081fd5b620017b08262001a5d565b6000806040838503121562001abe578081fd5b62001ac98362001a5d565b946020939093013593505050565b60006020828403121562001ae9578081fd5b81518015158114620017b0578182fd5b60008060006060848603121562001b0e578081fd5b62001b198462001a75565b925062001b296020850162001a75565b9150604084013590509250925092565b60006020828403121562001b4b578081fd5b5035919050565b60006020828403121562001b64578081fd5b5051919050565b6000825162001b7f8184602087016200224c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101562001c1d5783516001600160a01b03168352928401929184019160010162001bf6565b50909695505050505050565b901515815260200190565b6001600160a01b039485168152928416602084015292166040820152606081019190915260800190565b600060208252825180602084015262001c7f8160408501602087016200224c565b601f01601f19169190910160400192915050565b60208082526022908201527f5061796d656e7453706c69747465723a206163636f756e74206e6f7420666f756040820152611b9960f21b606082015260800190565b60208082526027908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f74206040820152666120706179656560c81b606082015260800190565b6020808252602a908201527f5061796d656e7453706c69747465723a206e6f7420656e6f756768207368617260408201526965732062616c616e636560b01b606082015260800190565b6020808252602c908201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060408201526b7a65726f206164647265737360a01b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526029908201527f5061796d656e7453706c69747465723a206163636f756e7420697320616c726560408201526861647920706179656560b81b606082015260800190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b60208082526028908201527f5061796d656e7453706c69747465723a207472616e73666572726572206e6f74604082015267206120706179656560c01b606082015260800190565b60208082526035908201527f5061796d656e7453706c69747465723a206163636f756e7420616c7265616479604082015274206861732074686174206d616e792073686172657360581b606082015260800190565b6020808252601c908201527f5061796d656e7453706c69747465723a206e6f74206120706179656500000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526021908201527f5061796d656e7453706c69747465723a20656d707479207061796565206c69736040820152601d60fa1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b602080825260149082015273496e646578206f7574206f6620626f756e64732160601b604082015260600190565b6020808252601d908201527f5061796d656e7453706c69747465723a20736861726573206172652030000000604082015260600190565b815181526020918201519181019190915260400190565b90815260200190565b9384526001600160801b0319928316602085015291166040830152606082015260800190565b600080821280156001600160ff1b03849003851316156200216d576200216d62002299565b600160ff1b839003841281161562002189576200218962002299565b50500190565b60008219821115620021a557620021a562002299565b500190565b600082620021c657634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615620021e857620021e862002299565b500290565b60008083128015600160ff1b8501841216156200220e576200220e62002299565b6001600160ff1b03840183138116156200222c576200222c62002299565b50500390565b60008282101562002247576200224762002299565b500390565b60005b83811015620022695781810151838201526020016200224f565b83811115620017965750506000910152565b600060001982141562002292576200229262002299565b5060010190565b634e487b7160e01b600052601160045260246000fdfe60e060405234801561001057600080fd5b50604051610c05380380610c0583398101604081905261002f91610166565b6000610039610162565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b0319166001600160a01b03868116919091179182905560408051630c4761ab60e11b81529051929091169163188ec35691600480820192602092909190829003018186803b1580156100df57600080fd5b505afa1580156100f3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061011791906101b8565b811161013e5760405162461bcd60e51b8152600401610135906101d0565b60405180910390fd5b6001600160601b0319606093841b81166080529190921b1660a05260c0525061023a565b3390565b6000806000806080858703121561017b578384fd5b845161018681610222565b602086015190945061019781610222565b60408601519093506101a881610222565b6060959095015193969295505050565b6000602082840312156101c9578081fd5b5051919050565b60208082526032908201527f546f6b656e54696d654c6f636b3a2072656c656173652074696d65206973206260408201527165666f72652063757272656e742074696d6560701b606082015260800190565b6001600160a01b038116811461023757600080fd5b50565b60805160601c60a05160601c60c05161099761026e600039600061036a0152600060ec0152600061044e01526109976000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638da5cb5b1161005b5780638da5cb5b146100b2578063b91d4001146100ba578063f2fde38b146100cf578063fc0c546a146100e25761007d565b806338af3eed14610082578063715018a6146100a057806386d1a69f146100aa575b600080fd5b61008a6100ea565b60405161009791906106f1565b60405180910390f35b6100a861010e565b005b6100a86101a0565b61008a610359565b6100c2610368565b6040516100979190610928565b6100a86100dd366004610676565b61038c565b61008a61044c565b7f000000000000000000000000000000000000000000000000000000000000000090565b610116610470565b6001600160a01b0316610127610359565b6001600160a01b0316146101565760405162461bcd60e51b815260040161014d90610872565b60405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6101a8610470565b6001600160a01b03166101b9610359565b6001600160a01b0316146101df5760405162461bcd60e51b815260040161014d90610872565b6101e7610368565b600160009054906101000a90046001600160a01b03166001600160a01b031663188ec3566040518163ffffffff1660e01b815260040160206040518083038186803b15801561023557600080fd5b505afa158015610249573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026d91906106bd565b101561028b5760405162461bcd60e51b815260040161014d90610820565b600061029561044c565b6001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016102c091906106f1565b60206040518083038186803b1580156102d857600080fd5b505afa1580156102ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031091906106bd565b9050600081116103325760405162461bcd60e51b815260040161014d90610797565b61035661033d6100ea565b8261034661044c565b6001600160a01b03169190610474565b50565b6000546001600160a01b031690565b7f000000000000000000000000000000000000000000000000000000000000000090565b610394610470565b6001600160a01b03166103a5610359565b6001600160a01b0316146103cb5760405162461bcd60e51b815260040161014d90610872565b6001600160a01b0381166103f15760405162461bcd60e51b815260040161014d90610751565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b7f000000000000000000000000000000000000000000000000000000000000000090565b3390565b6104ca8363a9059cbb60e01b8484604051602401610493929190610705565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526104cf565b505050565b6000610524826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661055e9092919063ffffffff16565b8051909150156104ca5780806020019051810190610542919061069d565b6104ca5760405162461bcd60e51b815260040161014d906108de565b606061056d8484600085610577565b90505b9392505050565b6060824710156105995760405162461bcd60e51b815260040161014d906107da565b6105a285610637565b6105be5760405162461bcd60e51b815260040161014d906108a7565b600080866001600160a01b031685876040516105da91906106d5565b60006040518083038185875af1925050503d8060008114610617576040519150601f19603f3d011682016040523d82523d6000602084013e61061c565b606091505b509150915061062c82828661063d565b979650505050505050565b3b151590565b6060831561064c575081610570565b82511561065c5782518084602001fd5b8160405162461bcd60e51b815260040161014d919061071e565b600060208284031215610687578081fd5b81356001600160a01b0381168114610570578182fd5b6000602082840312156106ae578081fd5b81518015158114610570578182fd5b6000602082840312156106ce578081fd5b5051919050565b600082516106e7818460208701610931565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b600060208252825180602084015261073d816040850160208701610931565b601f01601f19169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b60208082526023908201527f546f6b656e54696d654c6f636b3a206e6f20746f6b656e7320746f2072656c6560408201526261736560e81b606082015260800190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b60208082526032908201527f546f6b656e54696d654c6f636b3a2063757272656e742074696d65206973206260408201527165666f72652072656c656173652074696d6560701b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b90815260200190565b60005b8381101561094c578181015183820152602001610934565b8381111561095b576000848401525b5050505056fea26469706673582212201b2f059ff1f30db8b1ff5ab400f78c02543013e6e5f989a11129d6216fd72d4f64736f6c63430008000033a26469706673582212204de049cb9cef9bd9825dfb77577b0d16ae2aa00a8cca74cec4c51a9d7316c11264736f6c63430008000033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000227de4453a8840cd62e0d4336dc75b72ff89e5ce0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa8417400000000000000000000000076c1217105d2aa63d64367323091873f9754b563000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001803ff647ae147ae147ae147ae147ae147a000000000000000000000000000000004026d1a94a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000001a496e74657265737420466173746572205468616e204c6967687400000000000000000000000000000000000000000000000000000000000000000000000000044946544c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000028e19c0f68d34313320b10ba538299dc78f4192c000000000000000000000000150c1a134941cab797c1fca4f33ec1246076c578000000000000000000000000c0320245f52c1a9b7d6d22e07b1ffaae56afa5680000000000000000000000007826833c65a4a99310175140a447eb60ef2969360000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000032
-----Decoded View---------------
Arg [0] : _timestamp (address): 0x227DE4453a8840cD62E0d4336dC75B72fF89E5Ce
Arg [1] : _acceptedToken (address): 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
Arg [2] : _rewardCalculator (address): 0x76c1217105d2Aa63d64367323091873f9754B563
Arg [3] : _tokenName (string): Interest Faster Than Light
Arg [4] : _tokenSymbol (string): IFTL
Arg [5] : _interestRate (bytes16): 0x3ff647ae147ae147ae147ae147ae147a
Arg [6] : _multiplier (bytes16): 0x4026d1a94a2000000000000000000000
Arg [7] : _lockTime (uint256): 86400
Arg [8] : _payees (address[]): 0x28e19C0F68D34313320b10ba538299dc78F4192c,0x150C1a134941cab797C1FCA4F33EC1246076c578,0xc0320245f52C1a9b7d6D22E07B1fFAaE56AFA568,0x7826833c65A4a99310175140A447Eb60eF296936
Arg [9] : _shares (uint256[]): 10,10,30,50
-----Encoded View---------------
24 Constructor Arguments found :
Arg [0] : 000000000000000000000000227de4453a8840cd62e0d4336dc75b72ff89e5ce
Arg [1] : 0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174
Arg [2] : 00000000000000000000000076c1217105d2aa63d64367323091873f9754b563
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [5] : 3ff647ae147ae147ae147ae147ae147a00000000000000000000000000000000
Arg [6] : 4026d1a94a200000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000015180
Arg [8] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000260
Arg [10] : 000000000000000000000000000000000000000000000000000000000000001a
Arg [11] : 496e74657265737420466173746572205468616e204c69676874000000000000
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [13] : 4946544c00000000000000000000000000000000000000000000000000000000
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [15] : 00000000000000000000000028e19c0f68d34313320b10ba538299dc78f4192c
Arg [16] : 000000000000000000000000150c1a134941cab797c1fca4f33ec1246076c578
Arg [17] : 000000000000000000000000c0320245f52c1a9b7d6d22e07b1ffaae56afa568
Arg [18] : 0000000000000000000000007826833c65a4a99310175140a447eb60ef296936
Arg [19] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [20] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [21] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [22] : 000000000000000000000000000000000000000000000000000000000000001e
Arg [23] : 0000000000000000000000000000000000000000000000000000000000000032
Deployed Bytecode Sourcemap
106814:4042:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106374:115;;;;;;:::i;:::-;;:::i;:::-;;101029:745;;;;;;:::i;:::-;;:::i;109517:279::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100081:124;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;101782:107::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;99691:100::-;;;:::i;:::-;;;;;;;:::i;106621:95::-;;;;;;:::i;:::-;;:::i;109024:485::-;;;;;;:::i;:::-;;:::i;106061:121::-;;;;;;:::i;:::-;;:::i;109942:457::-;;;;;;:::i;:::-;;:::i;109804:130::-;;;:::i;:::-;;;;;;;:::i;107166:52::-;;;:::i;2843:148::-;;;:::i;100713:115::-;;;;;;:::i;:::-;;:::i;2192:87::-;;;:::i;102103:743::-;;;;;;:::i;:::-;;:::i;100507:115::-;;;;;;:::i;:::-;;:::i;108459:557::-;;;;;;:::i;:::-;;:::i;100296:111::-;;;;;;:::i;:::-;;:::i;99886:104::-;;;:::i;108161:290::-;;;;;;:::i;:::-;;:::i;3146:244::-;;;;;;:::i;:::-;;:::i;106374:115::-;2423:12;:10;:12::i;:::-;-1:-1:-1;;;;;2412:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2412:23:0;;2404:68;;;;-1:-1:-1;;;2404:68:0;;;;;;;:::i;:::-;;;;;;;;;106454:27:::1;106464:7;106473;106454:9;:27::i;:::-;106374:115:::0;;:::o;101029:745::-;101149:16;101157:7;101149;:16::i;:::-;101141:68;;;;-1:-1:-1;;;101141:68:0;;;;;;;:::i;:::-;101222:21;101288:15;:13;:15::i;:::-;101246:38;;-1:-1:-1;;;101246:38:0;;-1:-1:-1;;;;;101246:13:0;:23;;;;:38;;101278:4;;101246:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:57;;;;:::i;:::-;101222:81;;101314:15;101382:17;101391:7;101382:8;:17::i;:::-;101366:13;:11;:13::i;:::-;101348:15;101355:7;101348:6;:15::i;:::-;101332:31;;:13;:31;:::i;:::-;:47;;;;:::i;:::-;:67;;;;:::i;:::-;101314:85;-1:-1:-1;101472:12:0;101464:68;;;;-1:-1:-1;;;101464:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;101545:29:0;;:20;:29;;;:12;:29;;;;;;;:38;:49;;101587:7;;101545:20;:49;;101587:7;;101545:49;:::i;:::-;;;;-1:-1:-1;;101634:4:0;101605:20;:35;;;:12;:35;;;;;;;:44;:55;;101653:7;;101605:20;:55;;101653:7;;101605:55;:::i;:::-;;;;-1:-1:-1;101673:44:0;;-1:-1:-1;;;;;;101673:13:0;:26;101700:7;101709;101673:26;:44::i;:::-;101733:33;101749:7;101758;101733:33;;;;;;;:::i;:::-;;;;;;;;101029:745;;;:::o;109517:279::-;109591:13;109617:10;109630:12;:10;:12::i;:::-;-1:-1:-1;;;;;109682:18:0;;;;;;:14;:18;;;;;:25;109617;;-1:-1:-1;109661:46:0;;109653:79;;;;-1:-1:-1;;;109653:79:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;109750:18:0;;;;;;:14;:18;;;;;:38;;109769:18;;109750:38;;;;-1:-1:-1;;;109750:38:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;109750:38:0;;-1:-1:-1;;109517:279:0;;;;:::o;100081:124::-;100135:13;;:::i;:::-;-1:-1:-1;;;;;;100168:29:0;:20;:29;;;:12;:29;;;;;;;;;100161:36;;;;;;;;;;;;;;;;;;;;;100081:124::o;101782:107::-;101837:4;101879:1;101861:15;101868:7;101861:6;:15::i;:::-;:19;;101782:107;-1:-1:-1;;101782:107:0:o;99691:100::-;99735:7;99762:21;99777:4;99762:6;:21::i;:::-;99755:28;;99691:100;:::o;106621:95::-;2423:12;:10;:12::i;:::-;-1:-1:-1;;;;;2412:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2412:23:0;;2404:68;;;;-1:-1:-1;;;2404:68:0;;;;;;;:::i;:::-;106687:21:::1;106700:7;106687:12;:21::i;:::-;106621:95:::0;:::o;109024:485::-;109069:14;109086:12;:10;:12::i;:::-;109396:42;;-1:-1:-1;;;109396:42:0;;109069:29;;-1:-1:-1;;;;;;109396:17:0;:26;;;;:42;;109069:29;;109431:6;;109396:42;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;109464:37;109486:6;109494;109464:37;;;;;;;:::i;:::-;;;;;;;;109024:485;;:::o;106061:121::-;2423:12;:10;:12::i;:::-;-1:-1:-1;;;;;2412:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2412:23:0;;2404:68;;;;-1:-1:-1;;;2404:68:0;;;;;;;:::i;:::-;106144:30:::1;106157:7;106166;106144:12;:30::i;109942:457::-:0;110008:16;110027:12;:10;:12::i;:::-;-1:-1:-1;;;;;110079:24:0;;;;;;:14;:24;;;;;:31;110008;;-1:-1:-1;110058:52:0;;110050:85;;;;-1:-1:-1;;;110050:85:0;;;;;;;:::i;:::-;110146:27;110176:47;110194:8;110204:18;110176:17;:47::i;:::-;110146:77;;110234:11;110248:17;-1:-1:-1;;;;;110248:27:0;;110284:13;110248:51;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;110234:65;;110310:13;-1:-1:-1;;;;;110310:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110349:42;110374:8;110384:6;110349:42;;;;;;;:::i;:::-;;;;;;;;109942:457;;;;:::o;109804:130::-;109856:22;109898:14;:28;109913:12;:10;:12::i;:::-;-1:-1:-1;;;;;109898:28:0;-1:-1:-1;;;;;109898:28:0;;;;;;;;;;;;109891:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;109891:35:0;;;;;;;;;;;;;;;;;;;;;;;109804:130;:::o;107166:52::-;;;:::o;2843:148::-;2423:12;:10;:12::i;:::-;-1:-1:-1;;;;;2412:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2412:23:0;;2404:68;;;;-1:-1:-1;;;2404:68:0;;;;;;;:::i;:::-;2950:1:::1;2934:6:::0;;2913:40:::1;::::0;-1:-1:-1;;;;;2934:6:0;;::::1;::::0;2913:40:::1;::::0;2950:1;;2913:40:::1;2981:1;2964:19:::0;;-1:-1:-1;;;;;;2964:19:0::1;::::0;;2843:148::o;100713:115::-;100764:7;100791:12;:22;;100814:5;100791:29;;;;;;-1:-1:-1;;;100791:29:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;100791:29:0;;100713:115;-1:-1:-1;;100713:115:0:o;2192:87::-;2238:7;2265:6;-1:-1:-1;;;;;2265:6:0;2192:87;:::o;102103:743::-;102179:19;102201:12;:10;:12::i;:::-;102179:34;;102284:20;102292:11;102284:7;:20::i;:::-;102276:73;;;;-1:-1:-1;;;102276:73:0;;;;;;;:::i;:::-;102443:12;102420:19;102427:11;102420:6;:19::i;:::-;:35;;102412:90;;;;-1:-1:-1;;;102412:90:0;;;;;;;:::i;:::-;102564:59;102577:11;102610:12;102590:19;102597:11;102590:6;:19::i;:::-;:32;;;;:::i;:::-;102564:12;:59::i;:::-;102637:11;102645:2;102637:7;:11::i;:::-;102634:141;;;102664:41;102677:2;102692:12;102681:10;102688:2;102681:6;:10::i;:::-;:23;;;;:::i;102664:41::-;102634:141;;;102736:27;102746:2;102750:12;102736:9;:27::i;:::-;102790:48;102808:11;102821:2;102825:12;102790:48;;;;;;;;:::i;100507:115::-;100563:7;100590:15;100597:7;100590:6;:15::i;:::-;:24;;;;100507:115;-1:-1:-1;;100507:115:0:o;108459:557::-;108507:17;108527:12;:10;:12::i;:::-;108507:32;;108550;108564:9;108575:6;108550:13;:32::i;:::-;108610:9;;:24;;;-1:-1:-1;;;108610:24:0;;;;108593:14;;-1:-1:-1;;;;;108610:9:0;;:22;;:24;;;;;;;;;;;;;;:9;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108693:9;;108746:8;;108593:41;;-1:-1:-1;108645:27:0;;-1:-1:-1;;;;;108693:9:0;;;;108704:17;;108723:9;;108734:20;;108593:41;108734:20;:::i;:::-;108675:80;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;108766:25:0;;;;;;;:14;:25;;;;;;;:45;;;;;;;;;;;;;;;-1:-1:-1;;;;;;108766:45:0;;;;;;;108939:10;;108977:19;;108766:45;;-1:-1:-1;108822:17:0;:22;;;;;108766:45;;108896:16;:34;;;;;;108931:6;;-1:-1:-1;;;108939:10:0;;;;;;;108951:12;;;108965:31;;:9;:31;:::i;:::-;108896:101;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108822:186;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108459:557;;;;:::o;100296:111::-;100350:7;100377:15;100384:7;100377:6;:15::i;:::-;:22;;100296:111;-1:-1:-1;;100296:111:0:o;99886:104::-;99932:7;99959:23;99976:4;99959:8;:23::i;108161:290::-;2423:12;:10;:12::i;:::-;-1:-1:-1;;;;;2412:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2412:23:0;;2404:68;;;;-1:-1:-1;;;2404:68:0;;;;;;;:::i;:::-;108283:12:::1;:31:::0;;::::1;108325:27:::0;;::::1;-1:-1:-1::0;;;108325:27:0::1;108283:31:::0;;;::::1;-1:-1:-1::0;;;;;;108283:31:0;;::::1;::::0;;;::::1;;108325:27;;::::0;;108363:8:::1;:23:::0;;;108419:9:::1;::::0;:24:::1;::::0;;-1:-1:-1;;;108419:24:0;;;;-1:-1:-1;;;;;108419:9:0;;::::1;::::0;:22:::1;::::0;:24;;::::1;::::0;::::1;::::0;;;;;;;:9;:24;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;108397:19;:46:::0;-1:-1:-1;;;108161:290:0:o;3146:244::-;2423:12;:10;:12::i;:::-;-1:-1:-1;;;;;2412:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2412:23:0;;2404:68;;;;-1:-1:-1;;;2404:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;3235:22:0;::::1;3227:73;;;;-1:-1:-1::0;;;3227:73:0::1;;;;;;;:::i;:::-;3337:6;::::0;;3316:38:::1;::::0;-1:-1:-1;;;;;3316:38:0;;::::1;::::0;3337:6;::::1;::::0;3316:38:::1;::::0;::::1;3365:6;:17:::0;;-1:-1:-1;;;;;;3365:17:0::1;-1:-1:-1::0;;;;;3365:17:0;;;::::1;::::0;;;::::1;::::0;;3146:244::o;742:98::-;822:10;742:98;:::o;103913:622::-;-1:-1:-1;;;;;104045:21:0;;104037:78;;;;-1:-1:-1;;;104037:78:0;;;;;;;:::i;:::-;104144:1;104134:7;:11;104126:53;;;;-1:-1:-1;;;104126:53:0;;;;;;;:::i;:::-;104251:16;104259:7;104251;:16::i;:::-;104250:17;104242:71;;;;-1:-1:-1;;;104242:71:0;;;;;;;:::i;:::-;104326:22;:36;;:12;:36;;;;;;;;;;-1:-1:-1;;;;;;104326:36:0;-1:-1:-1;;;;;104326:36:0;;;;;;;;-1:-1:-1;104373:29:0;;;104326:36;104373:29;;;;;;;;:46;;;104459:4;104430:35;;;;:53;;104373:46;;-1:-1:-1;104430:53:0;;104373:46;;104430:53;:::i;:::-;;;;-1:-1:-1;;104499:28:0;;;;;;104510:7;;104519;;104499:28;:::i;14876:177::-;14959:86;14979:5;15009:23;;;15034:2;15038:5;14986:58;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;14986:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;14986:58:0;-1:-1:-1;;;;;;14986:58:0;;;;;;;;;;14959:19;:86::i;:::-;14876:177;;;:::o;104667:483::-;104785:22;:29;104777:79;;;;-1:-1:-1;;;104777:79:0;;;;;;;:::i;:::-;104877:31;104911:15;104918:7;104911:6;:15::i;:::-;-1:-1:-1;;;;;104944:29:0;;:20;:29;;;:12;:29;;;;;;;104937:36;;;;;104877:49;-1:-1:-1;104984:40:0;104992:22;104965:7;104984;:40::i;:::-;105081:24;;105064:4;105081:24;105035:35;;;:12;:35;;;;;:70;;:35;;105081:24;105035:70;;105081:24;;105035:70;:::i;:::-;;;;-1:-1:-1;;105121:21:0;;;;;;105134:7;;105121:21;:::i;103038:683::-;103121:16;103129:7;103121;:16::i;:::-;103113:57;;;;-1:-1:-1;;;103113:57:0;;;;;;;:::i;:::-;103185:12;103181:87;;103214:21;103227:7;103214:12;:21::i;:::-;103250:7;;103181:87;103357:7;103338:15;103345:7;103338:6;:15::i;:::-;:26;;103330:92;;;;-1:-1:-1;;;103330:92:0;;;;;;;:::i;:::-;103433:12;103473:15;103480:7;103473:6;:15::i;:::-;103448:41;;103455:7;103448:41;:::i;:::-;-1:-1:-1;;;;;103500:29:0;;:20;:29;;;:12;:29;;;;;;:46;;;103646:4;103617:35;;;;:42;103433:56;;-1:-1:-1;103610:58:0;;103433:56;;103610:58;:::i;:::-;103586:4;103557:20;:35;;;:12;:35;;;;;;;:112;;;;103685:28;;;;;103698:7;;103707:5;;103685:28;:::i;110407:446::-;-1:-1:-1;;;;;110543:22:0;;110493:13;110543:22;;;:14;:22;;;;;:42;;110493:13;;110543:22;110566:18;;110543:42;;;;-1:-1:-1;;;110543:42:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;110612:22:0;;;;;:14;:22;;;;;;:29;110543:42;;;-1:-1:-1;110612:33:0;;110543:42;;110612:33;:::i;:::-;-1:-1:-1;;;;;110701:22:0;;;;;;:14;:22;;;;;:32;;110596:49;;-1:-1:-1;110701:22:0;110596:49;;110701:32;;;;-1:-1:-1;;;110701:32:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;110656:22:0;;;;;:14;:22;;;;;;;:42;;110701:32;;;;;110656:22;110679:18;;110656:42;;;;-1:-1:-1;;;110656:42:0;;;;;;;;;;;;;;;;;;;;;:77;;-1:-1:-1;;;;;;110656:77:0;-1:-1:-1;;;;;110656:77:0;;;;;;110751:22;;;;;:14;:22;;;;;;:32;;110774:8;;110751:32;;;;-1:-1:-1;;;110751:32:0;;;;;;;;;;;;;;;;;;;;110744:39;;-1:-1:-1;;;;;;110744:39:0;;;-1:-1:-1;;;;;110794:22:0;;;;;:14;:22;;-1:-1:-1;110838:7:0;-1:-1:-1;110407:446:0;;;;;:::o;99412:196::-;99481:64;-1:-1:-1;;;;;99481:13:0;:30;99512:9;99531:4;99538:6;99481:30;:64::i;:::-;99561:39;99582:9;99593:6;99561:39;;;;;;;:::i;17310:761::-;17734:23;17760:69;17788:4;17760:69;;;;;;;;;;;;;;;;;17768:5;-1:-1:-1;;;;;17760:27:0;;;:69;;;;;:::i;:::-;17844:17;;17734:95;;-1:-1:-1;17844:21:0;17840:224;;17986:10;17975:30;;;;;;;;;;;;:::i;:::-;17967:85;;;;-1:-1:-1;;;17967:85:0;;;;;;;:::i;105509:123::-;105586:38;105594:4;105600:23;105609:4;105600:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;105600:23:0;;;;;;;;;;;;;;;;;;;;;105615:7;105600:8;:23::i;:::-;105586:7;:38::i;15061:205::-;15162:96;15182:5;15212:27;;;15241:4;15247:2;15251:5;15189:68;;;;;;;;;;:::i;15162:96::-;15061:205;;;;:::o;9900:195::-;10003:12;10035:52;10057:6;10065:4;10071:1;10074:12;10035:21;:52::i;:::-;10028:59;;9900:195;;;;;;:::o;105156:347::-;105236:7;;105255:134;105279:4;:11;105275:1;:15;105255:134;;;105326:8;-1:-1:-1;;;;;105315:19:0;:4;105320:1;105315:7;;;;;;-1:-1:-1;;;105315:7:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;105315:19:0;;105312:66;;;105361:1;-1:-1:-1;105354:8:0;;105312:66;105292:3;;;;:::i;:::-;;;;105255:134;;;;105451:44;;-1:-1:-1;;;105451:44:0;;;;;;;:::i;105638:231::-;105788:11;;105783:4;;105788:15;;105802:1;;105788:15;:::i;:::-;105783:21;;;;;;-1:-1:-1;;;105783:21:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;105783:21:0;105769:4;105774:5;105769:11;;;;;;-1:-1:-1;;;105769:11:0;;;;;;;;;;;;;;;;;:35;;;;;-1:-1:-1;;;;;105769:35:0;;;;;-1:-1:-1;;;;;105769:35:0;;;;;;105851:4;:10;;;;;-1:-1:-1;;;105851:10:0;;;;;;;;;;;;;;;;;;-1:-1:-1;;105851:10:0;;;;;-1:-1:-1;;;;;;105851:10:0;;;;;;-1:-1:-1;;105638:231:0:o;10952:530::-;11079:12;11137:5;11112:21;:30;;11104:81;;;;-1:-1:-1;;;11104:81:0;;;;;;;:::i;:::-;11204:18;11215:6;11204:10;:18::i;:::-;11196:60;;;;-1:-1:-1;;;11196:60:0;;;;;;;:::i;:::-;11330:12;11344:23;11371:6;-1:-1:-1;;;;;11371:11:0;11391:5;11399:4;11371:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11329:75;;;;11422:52;11440:7;11449:10;11461:12;11422:17;:52::i;:::-;11415:59;10952:530;-1:-1:-1;;;;;;;10952:530:0:o;6982:422::-;7349:20;7388:8;;;6982:422::o;13492:742::-;13607:12;13636:7;13632:595;;;-1:-1:-1;13667:10:0;13660:17;;13632:595;13781:17;;:21;13777:439;;14044:10;14038:17;14105:15;14092:10;14088:2;14084:19;14077:44;13992:148;14187:12;14180:20;;-1:-1:-1;;;14180:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::o;14:175:1:-;84:20;;-1:-1:-1;;;;;133:31:1;;123:42;;113:2;;179:1;176;169:12;194:195;264:20;;-1:-1:-1;;;;;;313:51:1;;303:62;;293:2;;379:1;376;369:12;394:198;;506:2;494:9;485:7;481:23;477:32;474:2;;;527:6;519;512:22;474:2;555:31;576:9;555:31;:::i;597:266::-;;;726:2;714:9;705:7;701:23;697:32;694:2;;;747:6;739;732:22;694:2;775:31;796:9;775:31;:::i;:::-;765:41;853:2;838:18;;;;825:32;;-1:-1:-1;;;684:179:1:o;868:297::-;;988:2;976:9;967:7;963:23;959:32;956:2;;;1009:6;1001;994:22;956:2;1046:9;1040:16;1099:5;1092:13;1085:21;1078:5;1075:32;1065:2;;1126:6;1118;1111:22;1170:342;;;;1316:2;1304:9;1295:7;1291:23;1287:32;1284:2;;;1337:6;1329;1322:22;1284:2;1365:31;1386:9;1365:31;:::i;:::-;1355:41;;1415:40;1451:2;1440:9;1436:18;1415:40;:::i;:::-;1405:50;;1502:2;1491:9;1487:18;1474:32;1464:42;;1274:238;;;;;:::o;1517:190::-;;1629:2;1617:9;1608:7;1604:23;1600:32;1597:2;;;1650:6;1642;1635:22;1597:2;-1:-1:-1;1678:23:1;;1587:120;-1:-1:-1;1587:120:1:o;1712:194::-;;1835:2;1823:9;1814:7;1810:23;1806:32;1803:2;;;1856:6;1848;1841:22;1803:2;-1:-1:-1;1884:16:1;;1793:113;-1:-1:-1;1793:113:1:o;1911:274::-;;2078:6;2072:13;2094:53;2140:6;2135:3;2128:4;2120:6;2116:17;2094:53;:::i;:::-;2163:16;;;;;2048:137;-1:-1:-1;;2048:137:1:o;2190:203::-;-1:-1:-1;;;;;2354:32:1;;;;2336:51;;2324:2;2309:18;;2291:102::o;2398:375::-;-1:-1:-1;;;;;2656:15:1;;;2638:34;;2708:15;;;;2703:2;2688:18;;2681:43;2755:2;2740:18;;2733:34;;;;2588:2;2573:18;;2555:218::o;2778:272::-;-1:-1:-1;;;;;2968:32:1;;;;2950:51;;3032:2;3017:18;;3010:34;2938:2;2923:18;;2905:145::o;3334:682::-;3526:2;3578:21;;;3648:13;;3551:18;;;3670:22;;;3334:682;;3526:2;3749:15;;;;3723:2;3708:18;;;3334:682;3795:195;3809:6;3806:1;3803:13;3795:195;;;3874:13;;-1:-1:-1;;;;;3870:39:1;3858:52;;3965:15;;;;3930:12;;;;3906:1;3824:9;3795:195;;;-1:-1:-1;4007:3:1;;3506:510;-1:-1:-1;;;;;;3506:510:1:o;4021:187::-;4186:14;;4179:22;4161:41;;4149:2;4134:18;;4116:92::o;4213:499::-;-1:-1:-1;;;;;4543:15:1;;;4525:34;;4595:15;;;4590:2;4575:18;;4568:43;4647:15;;4642:2;4627:18;;4620:43;4694:2;4679:18;;4672:34;;;;4474:3;4459:19;;4441:271::o;5180:383::-;;5329:2;5318:9;5311:21;5361:6;5355:13;5404:6;5399:2;5388:9;5384:18;5377:34;5420:66;5479:6;5474:2;5463:9;5459:18;5454:2;5446:6;5442:15;5420:66;:::i;:::-;5547:2;5526:15;-1:-1:-1;;5522:29:1;5507:45;;;;5554:2;5503:54;;5301:262;-1:-1:-1;;5301:262:1:o;5568:398::-;5770:2;5752:21;;;5809:2;5789:18;;;5782:30;5848:34;5843:2;5828:18;;5821:62;-1:-1:-1;;;5914:2:1;5899:18;;5892:32;5956:3;5941:19;;5742:224::o;5971:403::-;6173:2;6155:21;;;6212:2;6192:18;;;6185:30;6251:34;6246:2;6231:18;;6224:62;-1:-1:-1;;;6317:2:1;6302:18;;6295:37;6364:3;6349:19;;6145:229::o;6379:406::-;6581:2;6563:21;;;6620:2;6600:18;;;6593:30;6659:34;6654:2;6639:18;;6632:62;-1:-1:-1;;;6725:2:1;6710:18;;6703:40;6775:3;6760:19;;6553:232::o;6790:408::-;6992:2;6974:21;;;7031:2;7011:18;;;7004:30;7070:34;7065:2;7050:18;;7043:62;-1:-1:-1;;;7136:2:1;7121:18;;7114:42;7188:3;7173:19;;6964:234::o;7203:402::-;7405:2;7387:21;;;7444:2;7424:18;;;7417:30;7483:34;7478:2;7463:18;;7456:62;-1:-1:-1;;;7549:2:1;7534:18;;7527:36;7595:3;7580:19;;7377:228::o;7610:405::-;7812:2;7794:21;;;7851:2;7831:18;;;7824:30;7890:34;7885:2;7870:18;;7863:62;-1:-1:-1;;;7956:2:1;7941:18;;7934:39;8005:3;7990:19;;7784:231::o;8020:402::-;8222:2;8204:21;;;8261:2;8241:18;;;8234:30;8300:34;8295:2;8280:18;;8273:62;-1:-1:-1;;;8366:2:1;8351:18;;8344:36;8412:3;8397:19;;8194:228::o;8427:407::-;8629:2;8611:21;;;8668:2;8648:18;;;8641:30;8707:34;8702:2;8687:18;;8680:62;-1:-1:-1;;;8773:2:1;8758:18;;8751:41;8824:3;8809:19;;8601:233::o;8839:404::-;9041:2;9023:21;;;9080:2;9060:18;;;9053:30;9119:34;9114:2;9099:18;;9092:62;-1:-1:-1;;;9185:2:1;9170:18;;9163:38;9233:3;9218:19;;9013:230::o;9248:417::-;9450:2;9432:21;;;9489:2;9469:18;;;9462:30;9528:34;9523:2;9508:18;;9501:62;-1:-1:-1;;;9594:2:1;9579:18;;9572:51;9655:3;9640:19;;9422:243::o;9670:352::-;9872:2;9854:21;;;9911:2;9891:18;;;9884:30;9950;9945:2;9930:18;;9923:58;10013:2;9998:18;;9844:178::o;10027:356::-;10229:2;10211:21;;;10248:18;;;10241:30;10307:34;10302:2;10287:18;;10280:62;10374:2;10359:18;;10201:182::o;10388:397::-;10590:2;10572:21;;;10629:2;10609:18;;;10602:30;10668:34;10663:2;10648:18;;10641:62;-1:-1:-1;;;10734:2:1;10719:18;;10712:31;10775:3;10760:19;;10562:223::o;10790:353::-;10992:2;10974:21;;;11031:2;11011:18;;;11004:30;11070:31;11065:2;11050:18;;11043:59;11134:2;11119:18;;10964:179::o;11148:406::-;11350:2;11332:21;;;11389:2;11369:18;;;11362:30;11428:34;11423:2;11408:18;;11401:62;-1:-1:-1;;;11494:2:1;11479:18;;11472:40;11544:3;11529:19;;11322:232::o;11559:344::-;11761:2;11743:21;;;11800:2;11780:18;;;11773:30;-1:-1:-1;;;11834:2:1;11819:18;;11812:50;11894:2;11879:18;;11733:170::o;11908:353::-;12110:2;12092:21;;;12149:2;12129:18;;;12122:30;12188:31;12183:2;12168:18;;12161:59;12252:2;12237:18;;12082:179::o;12266:295::-;12478:13;;12460:32;;12548:4;12536:17;;;12530:24;12508:20;;;12501:54;;;;12448:2;12433:18;;12415:146::o;12566:177::-;12712:25;;;12700:2;12685:18;;12667:76::o;12748:467::-;12979:25;;;-1:-1:-1;;;;;;13098:15:1;;;13093:2;13078:18;;13071:43;13150:15;;13145:2;13130:18;;13123:43;13197:2;13182:18;;13175:34;12966:3;12951:19;;12933:282::o;13220:267::-;;13287:11;;;13314:10;;-1:-1:-1;;;;;13333:27:1;;;13326:35;;13310:52;13307:2;;;13365:18;;:::i;:::-;-1:-1:-1;;;13412:19:1;;;13405:27;;13397:36;;13394:2;;;13436:18;;:::i;:::-;-1:-1:-1;;13472:9:1;;13267:220::o;13492:128::-;;13563:1;13559:6;13556:1;13553:13;13550:2;;;13569:18;;:::i;:::-;-1:-1:-1;13605:9:1;;13540:80::o;13625:217::-;;13691:1;13681:2;;-1:-1:-1;;;13716:31:1;;13770:4;13767:1;13760:15;13798:4;13723:1;13788:15;13681:2;-1:-1:-1;13827:9:1;;13671:171::o;13847:168::-;;13953:1;13949;13945:6;13941:14;13938:1;13935:21;13930:1;13923:9;13916:17;13912:45;13909:2;;;13960:18;;:::i;:::-;-1:-1:-1;14000:9:1;;13899:116::o;14020:270::-;;14088:12;;;14116:10;;-1:-1:-1;;;14135:19:1;;14128:27;;14112:44;14109:2;;;14159:18;;:::i;:::-;-1:-1:-1;;;;;14206:27:1;;14199:35;;14191:44;;14188:2;;;14238:18;;:::i;:::-;-1:-1:-1;;14275:9:1;;14068:222::o;14295:125::-;;14363:1;14360;14357:8;14354:2;;;14368:18;;:::i;:::-;-1:-1:-1;14405:9:1;;14344:76::o;14425:258::-;14497:1;14507:113;14521:6;14518:1;14515:13;14507:113;;;14597:11;;;14591:18;14578:11;;;14571:39;14543:2;14536:10;14507:113;;;14638:6;14635:1;14632:13;14629:2;;;-1:-1:-1;;14673:1:1;14655:16;;14648:27;14478:205::o;14688:135::-;;-1:-1:-1;;14748:17:1;;14745:2;;;14768:18;;:::i;:::-;-1:-1:-1;14815:1:1;14804:13;;14735:88::o;14828:127::-;14889:10;14884:3;14880:20;14877:1;14870:31;14920:4;14917:1;14910:15;14944:4;14941:1;14934:15
Swarm Source
ipfs://dfcd22be314ee4e2f82a9ff983f1140f0667cd60bd850012541174bc185606bb
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.