More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,326,415 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 103079522 | 3 days ago | IN | 0 FTM | 0.0006725 | ||||
Withdraw | 103079504 | 3 days ago | IN | 0 FTM | 0.00072272 | ||||
Withdraw | 102884281 | 5 days ago | IN | 0 FTM | 0.00077712 | ||||
Withdraw | 102746970 | 7 days ago | IN | 0 FTM | 0.00061563 | ||||
Withdraw | 102685269 | 8 days ago | IN | 0 FTM | 0.11163725 | ||||
Withdraw | 102684933 | 8 days ago | IN | 0 FTM | 0.23573806 | ||||
Withdraw | 102258520 | 14 days ago | IN | 0 FTM | 0.25213698 | ||||
Withdraw | 102209307 | 15 days ago | IN | 0 FTM | 0.00065951 | ||||
Withdraw | 101989386 | 17 days ago | IN | 0 FTM | 0.00072321 | ||||
Withdraw | 101989361 | 17 days ago | IN | 0 FTM | 0.00072318 | ||||
Withdraw | 101957452 | 18 days ago | IN | 0 FTM | 0.00265193 | ||||
Withdraw | 101957410 | 18 days ago | IN | 0 FTM | 0.00265166 | ||||
Withdraw | 101887562 | 19 days ago | IN | 0 FTM | 0.00072329 | ||||
Withdraw | 101684027 | 21 days ago | IN | 0 FTM | 0.00014125 | ||||
Withdraw | 101684024 | 21 days ago | IN | 0 FTM | 0.00028024 | ||||
Withdraw | 101683955 | 21 days ago | IN | 0 FTM | 0.00077708 | ||||
Withdraw | 101286607 | 26 days ago | IN | 0 FTM | 0.00072849 | ||||
Withdraw | 101271321 | 26 days ago | IN | 0 FTM | 0.00065772 | ||||
Withdraw | 101184393 | 27 days ago | IN | 0 FTM | 0.00096434 | ||||
Withdraw | 101067751 | 28 days ago | IN | 0 FTM | 0.0008004 | ||||
Withdraw | 101067728 | 28 days ago | IN | 0 FTM | 0.0008004 | ||||
Withdraw | 101042196 | 29 days ago | IN | 0 FTM | 0.00081864 | ||||
Withdraw | 101039716 | 29 days ago | IN | 0 FTM | 0.00066466 | ||||
Withdraw | 100980448 | 29 days ago | IN | 0 FTM | 0.00095256 | ||||
Withdraw | 100957789 | 30 days ago | IN | 0 FTM | 0.00107434 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
4267037 | 1368 days ago | Contract Creation | 0 FTM |
Loading...
Loading
Contract Name:
MasterChef
Compiler Version
v0.8.0+commit.c7dfd78e
Contract Source Code (Solidity)
/** *Submitted for verification at ftmscan.com on 2021-04-25 */ // SPDX-License-Identifier: MIT 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); } /** * @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); } } } } /** * @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"); } } } // 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; } } } /* * @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; } } /** * @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 { 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 three 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 returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual 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 * overloaded; * * 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 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 { } } /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length if (signature.length != 65) { revert("ECDSA: invalid signature length"); } // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return recover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value"); require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value"); // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); require(signer != address(0), "ECDSA: invalid signature"); return signer; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712 { /* solhint-disable var-name-mixedcase */ // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) { return keccak256( abi.encode( typeHash, name, version, block.chainid, address(this) ) ); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } } /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } } // This version of ERC20Permit is from OpenZeppelin as of commit // https://github.com/OpenZeppelin/openzeppelin-contracts/commit/5171e46c47bd6be781aa92315944ca37126d4a73 /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { using Counters for Counters.Counter; mapping (address => Counters.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ constructor(string memory name) EIP712(name, "1") { } /** * @dev See {IERC20Permit-permit}. */ function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override { // solhint-disable-next-line not-rely-on-time require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256( abi.encode( _PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline ) ); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. */ function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } } /** * @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; } } contract SpookyToken is ERC20Permit, Ownable { constructor() ERC20("SpookyToken", "BOO") ERC20Permit("SpookyToken") { } uint256 constant private _maxTotalSupply = 13666000e18; // 13,666,000 max spooks function mint(address _to, uint256 _amount) public onlyOwner { require(totalSupply() + _amount <= _maxTotalSupply, "ERC20: minting more then MaxTotalSupply"); _mint(_to, _amount); _moveDelegates(address(0), _to, _amount); } // Returns maximum total supply of the token function getMaxTotalSupply() external pure returns (uint256) { return _maxTotalSupply; } // Copied and modified from YAM code: // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol // Which is copied and modified from COMPOUND: // https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol // A record of each accounts delegate mapping (address => address) internal _delegates; /// @notice A checkpoint for marking number of votes from a given block struct Checkpoint { uint32 fromBlock; uint256 votes; } /// @notice A record of votes checkpoints for each account, by index mapping (address => mapping (uint32 => Checkpoint)) public checkpoints; /// @notice The number of checkpoints for each account mapping (address => uint32) public numCheckpoints; /// @notice The EIP-712 typehash for the contract's domain bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)"); /// @notice The EIP-712 typehash for the delegation struct used by the contract bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)"); // A record of states for signing / validating signatures //mapping (address => uint) public nonces; /// @notice An event thats emitted when an account changes its delegate event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /// @notice An event thats emitted when a delegate account's vote balance changes event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance); function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { bool result = super.transferFrom(sender, recipient, amount); // Call parent hook _moveDelegates(sender, recipient, amount); return result; } function transfer(address recipient, uint256 amount) public virtual override returns (bool) { bool result = super.transfer(recipient, amount); // Call parent hook _moveDelegates(_msgSender(), recipient, amount); return result; } /** * @param delegator The address to get delegates for */ function delegates(address delegator) external view returns (address) { return _delegates[delegator]; } /** * @notice Delegate votes from `msg.sender` to `delegatee` * @param delegatee The address to delegate votes to */ function delegate(address delegatee) external { return _delegate(msg.sender, delegatee); } /** * @notice Delegates votes from signatory to `delegatee` * @param delegatee The address to delegate votes to * @param nonce The contract state required to match the signature * @param expiry The time at which to expire the signature * @param v The recovery byte of the signature * @param r Half of the ECDSA signature pair * @param s Half of the ECDSA signature pair */ function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s ) external { bytes32 domainSeparator = keccak256( abi.encode( DOMAIN_TYPEHASH, keccak256(bytes(name())), getChainId(), address(this) ) ); bytes32 structHash = keccak256( abi.encode( DELEGATION_TYPEHASH, delegatee, nonce, expiry ) ); bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", domainSeparator, structHash ) ); address signatory = ecrecover(digest, v, r, s); require(signatory != address(0), "SPOOK::delegateBySig: invalid signature"); require(nonce == _useNonce(signatory), "SPOOK::delegateBySig: invalid nonce"); require(block.timestamp <= expiry, "SPOOK::delegateBySig: signature expired"); return _delegate(signatory, delegatee); } /** * @notice Gets the current votes balance for `account` * @param account The address to get votes balance * @return The number of current votes for `account` */ function getCurrentVotes(address account) external view returns (uint256) { uint32 nCheckpoints = numCheckpoints[account]; return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0; } /** * @notice Determine the prior number of votes for an account as of a block number * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. * @param account The address of the account to check * @param blockNumber The block number to get the vote balance at * @return The number of votes the account had as of the given block */ function getPriorVotes(address account, uint blockNumber) external view returns (uint256) { require(blockNumber < block.number, "SPOOK::getPriorVotes: not yet determined"); uint32 nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; } // First check most recent balance if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { return checkpoints[account][nCheckpoints - 1].votes; } // Next check implicit zero balance if (checkpoints[account][0].fromBlock > blockNumber) { return 0; } uint32 lower = 0; uint32 upper = nCheckpoints - 1; while (upper > lower) { uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow Checkpoint memory cp = checkpoints[account][center]; if (cp.fromBlock == blockNumber) { return cp.votes; } else if (cp.fromBlock < blockNumber) { lower = center; } else { upper = center - 1; } } return checkpoints[account][lower].votes; } function _delegate(address delegator, address delegatee) internal { address currentDelegate = _delegates[delegator]; uint256 delegatorBalance = balanceOf(delegator); // balance of underlying SPOOKs (not scaled); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveDelegates(currentDelegate, delegatee, delegatorBalance); } function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal { if (srcRep != dstRep && amount > 0) { if (srcRep != address(0)) { // decrease old representative uint32 srcRepNum = numCheckpoints[srcRep]; uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0; uint256 srcRepNew = srcRepOld - amount; _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); } if (dstRep != address(0)) { // increase new representative uint32 dstRepNum = numCheckpoints[dstRep]; uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0; uint256 dstRepNew = dstRepOld + amount; _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); } } } function _writeCheckpoint( address delegatee, uint32 nCheckpoints, uint256 oldVotes, uint256 newVotes ) internal { uint32 blockNumber = safe32(block.number, "SPOOK::_writeCheckpoint: block number exceeds 32 bits"); if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; } else { checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); numCheckpoints[delegatee] = nCheckpoints + 1; } emit DelegateVotesChanged(delegatee, oldVotes, newVotes); } function safe32(uint n, string memory errorMessage) internal pure returns (uint32) { require(n < 2**32, errorMessage); return uint32(n); } function getChainId() internal view returns (uint) { uint256 chainId; assembly { chainId := chainid() } return chainId; } } contract MasterChef is Ownable { using SafeMath for uint256; using SafeERC20 for IERC20; // Info of each user. struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. // // We do some fancy math here. Basically, any point in time, the amount of BOOs // entitled to a user but is pending to be distributed is: // // pending reward = (user.amount * pool.accBOOPerShare) - user.rewardDebt // // Whenever a user deposits or withdraws LP tokens to a pool. Here's what happens: // 1. The pool's `accBOOPerShare` (and `lastRewardBlock`) gets updated. // 2. User receives the pending reward sent to his/her address. // 3. User's `amount` gets updated. // 4. User's `rewardDebt` gets updated. } // Info of each pool. struct PoolInfo { IERC20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. BOOs to distribute per block. uint256 lastRewardTime; // Last block time that BOOs distribution occurs. uint256 accBOOPerShare; // Accumulated BOOs per share, times 1e12. See below. } // such a spooky token! SpookyToken public boo; // Dev address. address public devaddr; // boo tokens created per block. uint256 public booPerSecond; // set a max boo per second, which can never be higher than 1 per second uint256 public constant maxBooPerSecond = 1e18; uint256 public constant MaxAllocPoint = 4000; // Info of each pool. PoolInfo[] public poolInfo; // Info of each user that stakes LP tokens. mapping (uint256 => mapping (address => UserInfo)) public userInfo; // Total allocation points. Must be the sum of all allocation points in all pools. uint256 public totalAllocPoint = 0; // The block time when boo mining starts. uint256 public immutable startTime; event Deposit(address indexed user, uint256 indexed pid, uint256 amount); event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount); constructor( SpookyToken _boo, address _devaddr, uint256 _booPerSecond, uint256 _startTime ) { boo = _boo; devaddr = _devaddr; booPerSecond = _booPerSecond; startTime = _startTime; } function poolLength() external view returns (uint256) { return poolInfo.length; } // Changes boo token reward per second, with a cap of maxboo per second // Good practice to update pools without messing up the contract function setBooPerSecond(uint256 _booPerSecond) external onlyOwner { require(_booPerSecond <= maxBooPerSecond, "setBooPerSecond: too many boos!"); // This MUST be done or pool rewards will be calculated with new boo per second // This could unfairly punish small pools that dont have frequent deposits/withdraws/harvests massUpdatePools(); booPerSecond = _booPerSecond; } function checkForDuplicate(IERC20 _lpToken) internal view { uint256 length = poolInfo.length; for (uint256 _pid = 0; _pid < length; _pid++) { require(poolInfo[_pid].lpToken != _lpToken, "add: pool already exists!!!!"); } } // Add a new lp to the pool. Can only be called by the owner. function add(uint256 _allocPoint, IERC20 _lpToken) external onlyOwner { require(_allocPoint <= MaxAllocPoint, "add: too many alloc points!!"); checkForDuplicate(_lpToken); // ensure you cant add duplicate pools massUpdatePools(); uint256 lastRewardTime = block.timestamp > startTime ? block.timestamp : startTime; totalAllocPoint = totalAllocPoint.add(_allocPoint); poolInfo.push(PoolInfo({ lpToken: _lpToken, allocPoint: _allocPoint, lastRewardTime: lastRewardTime, accBOOPerShare: 0 })); } // Update the given pool's boo allocation point. Can only be called by the owner. function set(uint256 _pid, uint256 _allocPoint) external onlyOwner { require(_allocPoint <= MaxAllocPoint, "add: too many alloc points!!"); massUpdatePools(); totalAllocPoint = totalAllocPoint - poolInfo[_pid].allocPoint + _allocPoint; poolInfo[_pid].allocPoint = _allocPoint; } // Return reward multiplier over the given _from to _to block. function getMultiplier(uint256 _from, uint256 _to) public view returns (uint256) { _from = _from > startTime ? _from : startTime; if (_to < startTime) { return 0; } return _to - _from; } // View function to see pending BOOs on frontend. function pendingBOO(uint256 _pid, address _user) external view returns (uint256) { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accBOOPerShare = pool.accBOOPerShare; uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (block.timestamp > pool.lastRewardTime && lpSupply != 0) { uint256 multiplier = getMultiplier(pool.lastRewardTime, block.timestamp); uint256 booReward = multiplier.mul(booPerSecond).mul(pool.allocPoint).div(totalAllocPoint); accBOOPerShare = accBOOPerShare.add(booReward.mul(1e12).div(lpSupply)); } return user.amount.mul(accBOOPerShare).div(1e12).sub(user.rewardDebt); } // Update reward variables for all pools. Be careful of gas spending! function massUpdatePools() public { uint256 length = poolInfo.length; for (uint256 pid = 0; pid < length; ++pid) { updatePool(pid); } } // Update reward variables of the given pool to be up-to-date. function updatePool(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; if (block.timestamp <= pool.lastRewardTime) { return; } uint256 lpSupply = pool.lpToken.balanceOf(address(this)); if (lpSupply == 0) { pool.lastRewardTime = block.timestamp; return; } uint256 multiplier = getMultiplier(pool.lastRewardTime, block.timestamp); uint256 booReward = multiplier.mul(booPerSecond).mul(pool.allocPoint).div(totalAllocPoint); boo.mint(devaddr, booReward.div(10)); boo.mint(address(this), booReward); pool.accBOOPerShare = pool.accBOOPerShare.add(booReward.mul(1e12).div(lpSupply)); pool.lastRewardTime = block.timestamp; } // Deposit LP tokens to MasterChef for boo allocation. function deposit(uint256 _pid, uint256 _amount) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; updatePool(_pid); uint256 pending = user.amount.mul(pool.accBOOPerShare).div(1e12).sub(user.rewardDebt); user.amount = user.amount.add(_amount); user.rewardDebt = user.amount.mul(pool.accBOOPerShare).div(1e12); if(pending > 0) { safeBOOTransfer(msg.sender, pending); } pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount); emit Deposit(msg.sender, _pid, _amount); } // Withdraw LP tokens from MasterChef. function withdraw(uint256 _pid, uint256 _amount) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; require(user.amount >= _amount, "withdraw: not good"); updatePool(_pid); uint256 pending = user.amount.mul(pool.accBOOPerShare).div(1e12).sub(user.rewardDebt); user.amount = user.amount.sub(_amount); user.rewardDebt = user.amount.mul(pool.accBOOPerShare).div(1e12); if(pending > 0) { safeBOOTransfer(msg.sender, pending); } pool.lpToken.safeTransfer(address(msg.sender), _amount); emit Withdraw(msg.sender, _pid, _amount); } // Withdraw without caring about rewards. EMERGENCY ONLY. function emergencyWithdraw(uint256 _pid) public { PoolInfo storage pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][msg.sender]; uint oldUserAmount = user.amount; user.amount = 0; user.rewardDebt = 0; pool.lpToken.safeTransfer(address(msg.sender), oldUserAmount); emit EmergencyWithdraw(msg.sender, _pid, oldUserAmount); } // Safe boo transfer function, just in case if rounding error causes pool to not have enough BOOs. function safeBOOTransfer(address _to, uint256 _amount) internal { uint256 booBal = boo.balanceOf(address(this)); if (_amount > booBal) { boo.transfer(_to, booBal); } else { boo.transfer(_to, _amount); } } // Update dev address by the previous dev. function dev(address _devaddr) public { require(msg.sender == devaddr, "dev: wut?"); devaddr = _devaddr; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract SpookyToken","name":"_boo","type":"address"},{"internalType":"address","name":"_devaddr","type":"address"},{"internalType":"uint256","name":"_booPerSecond","type":"uint256"},{"internalType":"uint256","name":"_startTime","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","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":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"MaxAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IERC20","name":"_lpToken","type":"address"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"boo","outputs":[{"internalType":"contract SpookyToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"booPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_devaddr","type":"address"}],"name":"dev","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devaddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"getMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxBooPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingBOO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTime","type":"uint256"},{"internalType":"uint256","name":"accBOOPerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_booPerSecond","type":"uint256"}],"name":"setBooPerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","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":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a060405260006006553480156200001657600080fd5b5060405162002204380380620022048339810160408190526200003991620000d2565b600062000045620000ce565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b039586166001600160a01b031991821617909155600280549490951693169290921790925560039190915560805262000137565b3390565b60008060008060808587031215620000e8578384fd5b8451620000f5816200011e565b602086015190945062000108816200011e565b6040860151606090960151949790965092505050565b6001600160a01b03811681146200013457600080fd5b50565b60805161208e62000176600039600081816105ce015281816105f501528181610e5b01528181610f3501528181610f5c0152610f86015261208e6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806378e97925116100e3578063a279b07f1161008c578063e2bbb15811610066578063e2bbb15814610301578063f2fde38b14610314578063f4b83c4c1461032757610198565b8063a279b07f146102de578063d12f410c146102f1578063d49e77cd146102f957610198565b80638dbb1e3a116100bd5780638dbb1e3a146102a25780638f990b8b146102b557806393f1a40b146102bd57610198565b806378e979251461027f5780638d88a90e146102875780638da5cb5b1461029a57610198565b806349f0c296116101455780635312ea8e1161011f5780635312ea8e1461025c578063630b5ba11461026f578063715018a61461027757610198565b806349f0c296146102215780634b3df2001461023457806351eb05a61461024957610198565b80631ab06ee5116101765780631ab06ee5146101e65780632b8bbbe8146101fb578063441a3e701461020e57610198565b8063081e3eda1461019d5780631526fe27146101bb57806317caf6f1146101de575b600080fd5b6101a561032f565b6040516101b29190611ee6565b60405180910390f35b6101ce6101c9366004611aa6565b610335565b6040516101b29493929190611bcc565b6101a5610386565b6101f96101f4366004611b17565b61038c565b005b6101f9610209366004611b05565b61050a565b6101f961021c366004611b17565b610743565b6101f961022f366004611aa6565b6108df565b61023c6109a1565b6040516101b29190611b54565b6101f9610257366004611aa6565b6109bd565b6101f961026a366004611aa6565b610c5e565b6101f9610d4c565b6101f9610d77565b6101a5610e59565b6101f9610295366004611a6a565b610e7d565b61023c610f15565b6101a56102b0366004611b17565b610f31565b6101a5610fc7565b6102d06102cb366004611ad6565b610fcd565b6040516101b2929190611eef565b6101a56102ec366004611ad6565b610ff1565b6101a56111ae565b61023c6111ba565b6101f961030f366004611b17565b6111d6565b6101f9610322366004611a6a565b61131d565b6101a561146a565b60045490565b6004818154811061034557600080fd5b6000918252602090912060049091020180546001820154600283015460039093015473ffffffffffffffffffffffffffffffffffffffff9092169350919084565b60065481565b610394611470565b73ffffffffffffffffffffffffffffffffffffffff166103b2610f15565b73ffffffffffffffffffffffffffffffffffffffff1614610408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b60405180910390fd5b610fa0811115610444576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611e52565b61044c610d4c565b8060048381548110610487577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060040201600101546006546104a69190611f8b565b6104b09190611efd565b60068190555080600483815481106104f1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060040201600101819055505050565b610512611470565b73ffffffffffffffffffffffffffffffffffffffff16610530610f15565b73ffffffffffffffffffffffffffffffffffffffff161461057d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b610fa08211156105b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611e52565b6105c281611474565b6105ca610d4c565b60007f00000000000000000000000000000000000000000000000000000000000000004211610619577f000000000000000000000000000000000000000000000000000000000000000061061b565b425b60065490915061062b9084611549565b6006556040805160808101825273ffffffffffffffffffffffffffffffffffffffff938416815260208101948552908101918252600060608201818152600480546001810182559281905292517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9290930291820180547fffffffffffffffffffffffff000000000000000000000000000000000000000016939095169290921790935592517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19c830155517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19d82015590517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e90910155565b60006004838154811061077f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000918252602080832086845260058252604080852033865290925292208054600490920290920192508311156107e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611e1b565b6107eb846109bd565b6000610825826001015461081f64e8d4a510006108198760030154876000015461155590919063ffffffff16565b90611561565b9061156d565b8254909150610834908561156d565b80835560038401546108519164e8d4a51000916108199190611555565b60018301558015610866576108663382611579565b82546108899073ffffffffffffffffffffffffffffffffffffffff16338661178a565b843373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568866040516108d09190611ee6565b60405180910390a35050505050565b6108e7611470565b73ffffffffffffffffffffffffffffffffffffffff16610905610f15565b73ffffffffffffffffffffffffffffffffffffffff1614610952576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b670de0b6b3a7640000811115610994576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611cad565b61099c610d4c565b600355565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6000600482815481106109f9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060040201905080600201544211610a1a5750610c5b565b80546040517f70a0823100000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190610a70903090600401611b54565b60206040518083038186803b158015610a8857600080fd5b505afa158015610a9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac09190611abe565b905080610ad4575042600290910155610c5b565b6000610ae4836002015442610f31565b90506000610b116006546108198660010154610b0b6003548761155590919063ffffffff16565b90611555565b60015460025491925073ffffffffffffffffffffffffffffffffffffffff908116916340c10f199116610b4584600a611561565b6040518363ffffffff1660e01b8152600401610b62929190611ba6565b600060405180830381600087803b158015610b7c57600080fd5b505af1158015610b90573d6000803e3d6000fd5b50506001546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911692506340c10f199150610bec9030908590600401611ba6565b600060405180830381600087803b158015610c0657600080fd5b505af1158015610c1a573d6000803e3d6000fd5b50505050610c48610c3d8461081964e8d4a510008561155590919063ffffffff16565b600386015490611549565b6003850155505042600290920191909155505b50565b600060048281548110610c9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600091825260208083208584526005825260408085203380875293528420805485825560018201959095556004909302018054909450919291610cf79173ffffffffffffffffffffffffffffffffffffffff91909116908361178a565b833373ffffffffffffffffffffffffffffffffffffffff167fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae059583604051610d3e9190611ee6565b60405180910390a350505050565b60045460005b81811015610d7357610d63816109bd565b610d6c81611fce565b9050610d52565b5050565b610d7f611470565b73ffffffffffffffffffffffffffffffffffffffff16610d9d610f15565b73ffffffffffffffffffffffffffffffffffffffff1614610dea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025473ffffffffffffffffffffffffffffffffffffffff163314610ece576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611d78565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b60007f00000000000000000000000000000000000000000000000000000000000000008311610f80577f0000000000000000000000000000000000000000000000000000000000000000610f82565b825b92507f0000000000000000000000000000000000000000000000000000000000000000821015610fb457506000610fc1565b610fbe8383611f8b565b90505b92915050565b60035481565b60056020908152600092835260408084209091529082529020805460019091015482565b6000806004848154811061102e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000918252602080832087845260058252604080852073ffffffffffffffffffffffffffffffffffffffff8981168752935280852060049485029092016003810154815492517f70a0823100000000000000000000000000000000000000000000000000000000815291975092959294929391909116916370a08231916110b791309101611b54565b60206040518083038186803b1580156110cf57600080fd5b505afa1580156110e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111079190611abe565b905083600201544211801561111b57508015155b1561117b576000611130856002015442610f31565b905060006111576006546108198860010154610b0b6003548761155590919063ffffffff16565b905061117661116f846108198464e8d4a51000611555565b8590611549565b935050505b6111a3836001015461081f64e8d4a5100061081986886000015461155590919063ffffffff16565b979650505050505050565b670de0b6b3a764000081565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b600060048381548110611212577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60009182526020808320868452600582526040808520338652909252922060049091029091019150611243846109bd565b6000611271826001015461081f64e8d4a510006108198760030154876000015461155590919063ffffffff16565b82549091506112809085611549565b808355600384015461129d9164e8d4a51000916108199190611555565b600183015580156112b2576112b23382611579565b82546112d69073ffffffffffffffffffffffffffffffffffffffff1633308761182b565b843373ffffffffffffffffffffffffffffffffffffffff167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15866040516108d09190611ee6565b611325611470565b73ffffffffffffffffffffffffffffffffffffffff16611343610f15565b73ffffffffffffffffffffffffffffffffffffffff1614611390576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b73ffffffffffffffffffffffffffffffffffffffff81166113dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611c50565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610fa081565b3390565b60045460005b81811015611544578273ffffffffffffffffffffffffffffffffffffffff16600482815481106114d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600091825260209091206004909102015473ffffffffffffffffffffffffffffffffffffffff161415611532576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611d41565b8061153c81611fce565b91505061147a565b505050565b6000610fbe8284611efd565b6000610fbe8284611f4e565b6000610fbe8284611f15565b6000610fbe8284611f8b565b6001546040517f70a0823100000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff16906370a08231906115d0903090600401611b54565b60206040518083038186803b1580156115e857600080fd5b505afa1580156115fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116209190611abe565b9050808211156116da576001546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906116829086908590600401611ba6565b602060405180830381600087803b15801561169c57600080fd5b505af11580156116b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d49190611a86565b50611544565b6001546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906117329086908690600401611ba6565b602060405180830381600087803b15801561174c57600080fd5b505af1158015611760573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117849190611a86565b50505050565b6115448363a9059cbb60e01b84846040516024016117a9929190611ba6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261184c565b611784846323b872dd60e01b8585856040516024016117a993929190611b75565b60006118ae826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119029092919063ffffffff16565b80519091501561154457808060200190518101906118cc9190611a86565b611544576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611e89565b6060611911848460008561191b565b90505b9392505050565b606082471015611957576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611ce4565b61196085611a11565b611996576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611de4565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516119bf9190611b38565b60006040518083038185875af1925050503d80600081146119fc576040519150601f19603f3d011682016040523d82523d6000602084013e611a01565b606091505b50915091506111a3828286611a17565b3b151590565b60608315611a26575081611914565b825115611a365782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff9190611bff565b600060208284031215611a7b578081fd5b813561191481612036565b600060208284031215611a97578081fd5b81518015158114611914578182fd5b600060208284031215611ab7578081fd5b5035919050565b600060208284031215611acf578081fd5b5051919050565b60008060408385031215611ae8578081fd5b823591506020830135611afa81612036565b809150509250929050565b60008060408385031215611ae8578182fd5b60008060408385031215611b29578182fd5b50508035926020909101359150565b60008251611b4a818460208701611fa2565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff94909416845260208401929092526040830152606082015260800190565b6000602082528251806020840152611c1e816040850160208701611fa2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f736574426f6f5065725365636f6e643a20746f6f206d616e7920626f6f732100604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60408201527f722063616c6c0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601c908201527f6164643a20706f6f6c20616c7265616479206578697374732121212100000000604082015260600190565b60208082526009908201527f6465763a207775743f0000000000000000000000000000000000000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526012908201527f77697468647261773a206e6f7420676f6f640000000000000000000000000000604082015260600190565b6020808252601c908201527f6164643a20746f6f206d616e7920616c6c6f6320706f696e7473212100000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b90815260200190565b918252602082015260400190565b60008219821115611f1057611f10612007565b500190565b600082611f49577f4e487b710000000000000000000000000000000000000000000000000000000081526012600452602481fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611f8657611f86612007565b500290565b600082821015611f9d57611f9d612007565b500390565b60005b83811015611fbd578181015183820152602001611fa5565b838111156117845750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561200057612000612007565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610c5b57600080fdfea2646970667358221220ceeaa6b250749868c1bde500eca161bac4325233457a12976ea0cb80b20145d864736f6c63430008000033000000000000000000000000841fad6eae12c286d1fd18d1d525dffa75c7effe00000000000000000000000095478c4f7d22d1048f46100001c2c69d2ba573800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005efb32f4
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101985760003560e01c806378e97925116100e3578063a279b07f1161008c578063e2bbb15811610066578063e2bbb15814610301578063f2fde38b14610314578063f4b83c4c1461032757610198565b8063a279b07f146102de578063d12f410c146102f1578063d49e77cd146102f957610198565b80638dbb1e3a116100bd5780638dbb1e3a146102a25780638f990b8b146102b557806393f1a40b146102bd57610198565b806378e979251461027f5780638d88a90e146102875780638da5cb5b1461029a57610198565b806349f0c296116101455780635312ea8e1161011f5780635312ea8e1461025c578063630b5ba11461026f578063715018a61461027757610198565b806349f0c296146102215780634b3df2001461023457806351eb05a61461024957610198565b80631ab06ee5116101765780631ab06ee5146101e65780632b8bbbe8146101fb578063441a3e701461020e57610198565b8063081e3eda1461019d5780631526fe27146101bb57806317caf6f1146101de575b600080fd5b6101a561032f565b6040516101b29190611ee6565b60405180910390f35b6101ce6101c9366004611aa6565b610335565b6040516101b29493929190611bcc565b6101a5610386565b6101f96101f4366004611b17565b61038c565b005b6101f9610209366004611b05565b61050a565b6101f961021c366004611b17565b610743565b6101f961022f366004611aa6565b6108df565b61023c6109a1565b6040516101b29190611b54565b6101f9610257366004611aa6565b6109bd565b6101f961026a366004611aa6565b610c5e565b6101f9610d4c565b6101f9610d77565b6101a5610e59565b6101f9610295366004611a6a565b610e7d565b61023c610f15565b6101a56102b0366004611b17565b610f31565b6101a5610fc7565b6102d06102cb366004611ad6565b610fcd565b6040516101b2929190611eef565b6101a56102ec366004611ad6565b610ff1565b6101a56111ae565b61023c6111ba565b6101f961030f366004611b17565b6111d6565b6101f9610322366004611a6a565b61131d565b6101a561146a565b60045490565b6004818154811061034557600080fd5b6000918252602090912060049091020180546001820154600283015460039093015473ffffffffffffffffffffffffffffffffffffffff9092169350919084565b60065481565b610394611470565b73ffffffffffffffffffffffffffffffffffffffff166103b2610f15565b73ffffffffffffffffffffffffffffffffffffffff1614610408576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b60405180910390fd5b610fa0811115610444576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611e52565b61044c610d4c565b8060048381548110610487577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060040201600101546006546104a69190611f8b565b6104b09190611efd565b60068190555080600483815481106104f1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060040201600101819055505050565b610512611470565b73ffffffffffffffffffffffffffffffffffffffff16610530610f15565b73ffffffffffffffffffffffffffffffffffffffff161461057d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b610fa08211156105b9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611e52565b6105c281611474565b6105ca610d4c565b60007f000000000000000000000000000000000000000000000000000000005efb32f44211610619577f000000000000000000000000000000000000000000000000000000005efb32f461061b565b425b60065490915061062b9084611549565b6006556040805160808101825273ffffffffffffffffffffffffffffffffffffffff938416815260208101948552908101918252600060608201818152600480546001810182559281905292517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9290930291820180547fffffffffffffffffffffffff000000000000000000000000000000000000000016939095169290921790935592517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19c830155517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19d82015590517f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e90910155565b60006004838154811061077f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000918252602080832086845260058252604080852033865290925292208054600490920290920192508311156107e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611e1b565b6107eb846109bd565b6000610825826001015461081f64e8d4a510006108198760030154876000015461155590919063ffffffff16565b90611561565b9061156d565b8254909150610834908561156d565b80835560038401546108519164e8d4a51000916108199190611555565b60018301558015610866576108663382611579565b82546108899073ffffffffffffffffffffffffffffffffffffffff16338661178a565b843373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b568866040516108d09190611ee6565b60405180910390a35050505050565b6108e7611470565b73ffffffffffffffffffffffffffffffffffffffff16610905610f15565b73ffffffffffffffffffffffffffffffffffffffff1614610952576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b670de0b6b3a7640000811115610994576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611cad565b61099c610d4c565b600355565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b6000600482815481106109f9577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060040201905080600201544211610a1a5750610c5b565b80546040517f70a0823100000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190610a70903090600401611b54565b60206040518083038186803b158015610a8857600080fd5b505afa158015610a9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ac09190611abe565b905080610ad4575042600290910155610c5b565b6000610ae4836002015442610f31565b90506000610b116006546108198660010154610b0b6003548761155590919063ffffffff16565b90611555565b60015460025491925073ffffffffffffffffffffffffffffffffffffffff908116916340c10f199116610b4584600a611561565b6040518363ffffffff1660e01b8152600401610b62929190611ba6565b600060405180830381600087803b158015610b7c57600080fd5b505af1158015610b90573d6000803e3d6000fd5b50506001546040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911692506340c10f199150610bec9030908590600401611ba6565b600060405180830381600087803b158015610c0657600080fd5b505af1158015610c1a573d6000803e3d6000fd5b50505050610c48610c3d8461081964e8d4a510008561155590919063ffffffff16565b600386015490611549565b6003850155505042600290920191909155505b50565b600060048281548110610c9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600091825260208083208584526005825260408085203380875293528420805485825560018201959095556004909302018054909450919291610cf79173ffffffffffffffffffffffffffffffffffffffff91909116908361178a565b833373ffffffffffffffffffffffffffffffffffffffff167fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae059583604051610d3e9190611ee6565b60405180910390a350505050565b60045460005b81811015610d7357610d63816109bd565b610d6c81611fce565b9050610d52565b5050565b610d7f611470565b73ffffffffffffffffffffffffffffffffffffffff16610d9d610f15565b73ffffffffffffffffffffffffffffffffffffffff1614610dea576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b6000805460405173ffffffffffffffffffffffffffffffffffffffff909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b7f000000000000000000000000000000000000000000000000000000005efb32f481565b60025473ffffffffffffffffffffffffffffffffffffffff163314610ece576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611d78565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60005473ffffffffffffffffffffffffffffffffffffffff1690565b60007f000000000000000000000000000000000000000000000000000000005efb32f48311610f80577f000000000000000000000000000000000000000000000000000000005efb32f4610f82565b825b92507f000000000000000000000000000000000000000000000000000000005efb32f4821015610fb457506000610fc1565b610fbe8383611f8b565b90505b92915050565b60035481565b60056020908152600092835260408084209091529082529020805460019091015482565b6000806004848154811061102e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000918252602080832087845260058252604080852073ffffffffffffffffffffffffffffffffffffffff8981168752935280852060049485029092016003810154815492517f70a0823100000000000000000000000000000000000000000000000000000000815291975092959294929391909116916370a08231916110b791309101611b54565b60206040518083038186803b1580156110cf57600080fd5b505afa1580156110e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111079190611abe565b905083600201544211801561111b57508015155b1561117b576000611130856002015442610f31565b905060006111576006546108198860010154610b0b6003548761155590919063ffffffff16565b905061117661116f846108198464e8d4a51000611555565b8590611549565b935050505b6111a3836001015461081f64e8d4a5100061081986886000015461155590919063ffffffff16565b979650505050505050565b670de0b6b3a764000081565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b600060048381548110611212577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60009182526020808320868452600582526040808520338652909252922060049091029091019150611243846109bd565b6000611271826001015461081f64e8d4a510006108198760030154876000015461155590919063ffffffff16565b82549091506112809085611549565b808355600384015461129d9164e8d4a51000916108199190611555565b600183015580156112b2576112b23382611579565b82546112d69073ffffffffffffffffffffffffffffffffffffffff1633308761182b565b843373ffffffffffffffffffffffffffffffffffffffff167f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a15866040516108d09190611ee6565b611325611470565b73ffffffffffffffffffffffffffffffffffffffff16611343610f15565b73ffffffffffffffffffffffffffffffffffffffff1614611390576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611daf565b73ffffffffffffffffffffffffffffffffffffffff81166113dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611c50565b6000805460405173ffffffffffffffffffffffffffffffffffffffff808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610fa081565b3390565b60045460005b81811015611544578273ffffffffffffffffffffffffffffffffffffffff16600482815481106114d3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600091825260209091206004909102015473ffffffffffffffffffffffffffffffffffffffff161415611532576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611d41565b8061153c81611fce565b91505061147a565b505050565b6000610fbe8284611efd565b6000610fbe8284611f4e565b6000610fbe8284611f15565b6000610fbe8284611f8b565b6001546040517f70a0823100000000000000000000000000000000000000000000000000000000815260009173ffffffffffffffffffffffffffffffffffffffff16906370a08231906115d0903090600401611b54565b60206040518083038186803b1580156115e857600080fd5b505afa1580156115fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116209190611abe565b9050808211156116da576001546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906116829086908590600401611ba6565b602060405180830381600087803b15801561169c57600080fd5b505af11580156116b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116d49190611a86565b50611544565b6001546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091169063a9059cbb906117329086908690600401611ba6565b602060405180830381600087803b15801561174c57600080fd5b505af1158015611760573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117849190611a86565b50505050565b6115448363a9059cbb60e01b84846040516024016117a9929190611ba6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261184c565b611784846323b872dd60e01b8585856040516024016117a993929190611b75565b60006118ae826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166119029092919063ffffffff16565b80519091501561154457808060200190518101906118cc9190611a86565b611544576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611e89565b6060611911848460008561191b565b90505b9392505050565b606082471015611957576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611ce4565b61196085611a11565b611996576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff90611de4565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516119bf9190611b38565b60006040518083038185875af1925050503d80600081146119fc576040519150601f19603f3d011682016040523d82523d6000602084013e611a01565b606091505b50915091506111a3828286611a17565b3b151590565b60608315611a26575081611914565b825115611a365782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103ff9190611bff565b600060208284031215611a7b578081fd5b813561191481612036565b600060208284031215611a97578081fd5b81518015158114611914578182fd5b600060208284031215611ab7578081fd5b5035919050565b600060208284031215611acf578081fd5b5051919050565b60008060408385031215611ae8578081fd5b823591506020830135611afa81612036565b809150509250929050565b60008060408385031215611ae8578182fd5b60008060408385031215611b29578182fd5b50508035926020909101359150565b60008251611b4a818460208701611fa2565b9190910192915050565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff9384168152919092166020820152604081019190915260600190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b73ffffffffffffffffffffffffffffffffffffffff94909416845260208401929092526040830152606082015260800190565b6000602082528251806020840152611c1e816040850160208701611fa2565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201527f6464726573730000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601f908201527f736574426f6f5065725365636f6e643a20746f6f206d616e7920626f6f732100604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60408201527f722063616c6c0000000000000000000000000000000000000000000000000000606082015260800190565b6020808252601c908201527f6164643a20706f6f6c20616c7265616479206578697374732121212100000000604082015260600190565b60208082526009908201527f6465763a207775743f0000000000000000000000000000000000000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526012908201527f77697468647261773a206e6f7420676f6f640000000000000000000000000000604082015260600190565b6020808252601c908201527f6164643a20746f6f206d616e7920616c6c6f6320706f696e7473212100000000604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60408201527f6f74207375636365656400000000000000000000000000000000000000000000606082015260800190565b90815260200190565b918252602082015260400190565b60008219821115611f1057611f10612007565b500190565b600082611f49577f4e487b710000000000000000000000000000000000000000000000000000000081526012600452602481fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611f8657611f86612007565b500290565b600082821015611f9d57611f9d612007565b500390565b60005b83811015611fbd578181015183820152602001611fa5565b838111156117845750506000910152565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561200057612000612007565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff81168114610c5b57600080fdfea2646970667358221220ceeaa6b250749868c1bde500eca161bac4325233457a12976ea0cb80b20145d864736f6c63430008000033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000841fad6eae12c286d1fd18d1d525dffa75c7effe00000000000000000000000095478c4f7d22d1048f46100001c2c69d2ba573800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005efb32f4
-----Decoded View---------------
Arg [0] : _boo (address): 0x841FAD6EAe12c286d1Fd18d1d525DFfA75C7EFFE
Arg [1] : _devaddr (address): 0x95478C4F7D22D1048F46100001c2C69D2BA57380
Arg [2] : _booPerSecond (uint256): 0
Arg [3] : _startTime (uint256): 1593520884
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000841fad6eae12c286d1fd18d1d525dffa75c7effe
Arg [1] : 00000000000000000000000095478c4f7d22d1048f46100001c2c69d2ba57380
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 000000000000000000000000000000000000000000000000000000005efb32f4
Deployed Bytecode Sourcemap
60105:9503:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62747:95;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61851:26;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;62094:34::-;;;:::i;64487:323::-;;;;;;:::i;:::-;;:::i;:::-;;63775:617;;;;;;:::i;:::-;;:::i;67844:713::-;;;;;;:::i;:::-;;:::i;62997:426::-;;;;;;:::i;:::-;;:::i;61483:22::-;;;:::i;:::-;;;;;;;:::i;66283:785::-;;;;;;:::i;:::-;;:::i;68628:409::-;;;;;;:::i;:::-;;:::i;66027:180::-;;;:::i;49841:148::-;;;:::i;62182:34::-;;;:::i;69476:129::-;;;;;;:::i;:::-;;:::i;49190:87::-;;;:::i;64886:240::-;;;;;;:::i;:::-;;:::i;61602:27::-;;;:::i;61933:66::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;65189:755::-;;;;;;:::i;:::-;;:::i;61716:46::-;;;:::i;61535:22::-;;;:::i;67136:656::-;;;;;;:::i;:::-;;:::i;50144:244::-;;;;;;:::i;:::-;;:::i;61771:44::-;;;:::i;62747:95::-;62819:8;:15;62747:95;:::o;61851:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;61851:26:0;;;:::o;62094:34::-;;;;:::o;64487:323::-;49421:12;:10;:12::i;:::-;49410:23;;:7;:5;:7::i;:::-;:23;;;49402:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61811:4:::1;64573:11;:28;;64565:69;;;;;;;;;;;;:::i;:::-;64647:17;:15;:17::i;:::-;64741:11;64713:8;64722:4;64713:14;;;;;;;;;;;;;;;;;;;;;;;;;;:25;;;64695:15;;:43;;;;:::i;:::-;:57;;;;:::i;:::-;64677:15;:75;;;;64791:11;64763:8;64772:4;64763:14;;;;;;;;;;;;;;;;;;;;;;;;;;:25;;:39;;;;64487:323:::0;;:::o;63775:617::-;49421:12;:10;:12::i;:::-;49410:23;;:7;:5;:7::i;:::-;:23;;;49402:68;;;;;;;;;;;;:::i;:::-;61811:4:::1;63864:11;:28;;63856:69;;;;;;;;;;;;:::i;:::-;63938:27;63956:8;63938:17;:27::i;:::-;64017:17;:15;:17::i;:::-;64047:22;64090:9;64072:15;:27;:57;;64120:9;64072:57;;;64102:15;64072:57;64158:15;::::0;64047:82;;-1:-1:-1;64158:32:0::1;::::0;64178:11;64158:19:::1;:32::i;:::-;64140:15;:50:::0;64215:168:::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;-1:-1:-1;64215:168:0;;;;;;64201:8:::1;:183:::0;;::::1;::::0;::::1;::::0;;;;;;;;;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;;;;;;;;;;;;;;;;;;;63775:617::o;67844:713::-;67913:21;67937:8;67946:4;67937:14;;;;;;;;;;;;;;;;;;;;;;;;67986;;;:8;:14;;;;;;68001:10;67986:26;;;;;;;68033:11;;67937:14;;;;;;;;-1:-1:-1;68033:22:0;-1:-1:-1;68033:22:0;68025:53;;;;;;;;;;;;:::i;:::-;68091:16;68102:4;68091:10;:16::i;:::-;68120:15;68138:67;68189:4;:15;;;68138:46;68179:4;68138:36;68154:4;:19;;;68138:4;:11;;;:15;;:36;;;;:::i;:::-;:40;;:46::i;:::-;:50;;:67::i;:::-;68232:11;;68120:85;;-1:-1:-1;68232:24:0;;68248:7;68232:15;:24::i;:::-;68218:38;;;68301:19;;;;68285:46;;68326:4;;68285:36;;68218:38;68285:15;:36::i;:46::-;68267:15;;;:64;68347:11;;68344:79;;68375:36;68391:10;68403:7;68375:15;:36::i;:::-;68433:12;;:55;;:12;;68467:10;68480:7;68433:25;:55::i;:::-;68535:4;68523:10;68514:35;;;68541:7;68514:35;;;;;;:::i;:::-;;;;;;;;67844:713;;;;;:::o;62997:426::-;49421:12;:10;:12::i;:::-;49410:23;;:7;:5;:7::i;:::-;:23;;;49402:68;;;;;;;;;;;;:::i;:::-;61758:4:::1;63083:13;:32;;63075:76;;;;;;;;;;;;:::i;:::-;63356:17;:15;:17::i;:::-;63387:12;:28:::0;62997:426::o;61483:22::-;;;;;;:::o;66283:785::-;66335:21;66359:8;66368:4;66359:14;;;;;;;;;;;;;;;;;;;;;;;;;;66335:38;;66407:4;:19;;;66388:15;:38;66384:77;;66443:7;;;66384:77;66490:12;;:37;;;;;66471:16;;66490:12;;;:22;;:37;;66521:4;;66490:37;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66471:56;-1:-1:-1;66542:13:0;66538:104;;-1:-1:-1;66594:15:0;66572:19;;;;:37;66624:7;;66538:104;66652:18;66673:51;66687:4;:19;;;66708:15;66673:13;:51::i;:::-;66652:72;;66735:17;66755:70;66809:15;;66755:49;66788:4;:15;;;66755:28;66770:12;;66755:10;:14;;:28;;;;:::i;:::-;:32;;:49::i;:70::-;66838:3;;66847:7;;66735:90;;-1:-1:-1;66838:3:0;;;;;:8;;66847:7;66856:17;66735:90;66870:2;66856:13;:17::i;:::-;66838:36;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;66885:3:0;;:34;;;;;:3;;;;;-1:-1:-1;66885:8:0;;-1:-1:-1;66885:34:0;;66902:4;;66909:9;;66885:34;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66954:58;66978:33;67002:8;66978:19;66992:4;66978:9;:13;;:19;;;;:::i;:33::-;66954:19;;;;;:23;:58::i;:::-;66932:19;;;:80;-1:-1:-1;;67045:15:0;67023:19;;;;:37;;;;-1:-1:-1;66283:785:0;;:::o;68628:409::-;68687:21;68711:8;68720:4;68711:14;;;;;;;;;;;;;;;;;;;;;;;;68760;;;:8;:14;;;;;;68775:10;68760:26;;;;;;;68820:11;;68842:15;;;-1:-1:-1;68868:15:0;;:19;;;;68711:14;;;;;68900:12;;68711:14;;-1:-1:-1;68760:26:0;;68820:11;68900:61;;68760:26;68900:12;;;;;68820:11;68900:25;:61::i;:::-;69007:4;68995:10;68977:50;;;69013:13;68977:50;;;;;;:::i;:::-;;;;;;;;68628:409;;;;:::o;66027:180::-;66089:8;:15;66072:14;66115:85;66143:6;66137:3;:12;66115:85;;;66173:15;66184:3;66173:10;:15::i;:::-;66151:5;;;:::i;:::-;;;66115:85;;;;66027:180;:::o;49841:148::-;49421:12;:10;:12::i;:::-;49410:23;;:7;:5;:7::i;:::-;:23;;;49402:68;;;;;;;;;;;;:::i;:::-;49948:1:::1;49932:6:::0;;49911:40:::1;::::0;::::1;49932:6:::0;;::::1;::::0;49911:40:::1;::::0;49948:1;;49911:40:::1;49979:1;49962:19:::0;;;::::1;::::0;;49841:148::o;62182:34::-;;;:::o;69476:129::-;69547:7;;;;69533:10;:21;69525:43;;;;;;;;;;;;:::i;:::-;69579:7;:18;;;;;;;;;;;;;;;69476:129::o;49190:87::-;49236:7;49263:6;;;49190:87;:::o;64886:240::-;64958:7;64994:9;64986:5;:17;:37;;65014:9;64986:37;;;65006:5;64986:37;64978:45;;65044:9;65038:3;:15;65034:56;;;-1:-1:-1;65077:1:0;65070:8;;65034:56;65107:11;65113:5;65107:3;:11;:::i;:::-;65100:18;;64886:240;;;;;:::o;61602:27::-;;;;:::o;61933:66::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;65189:755::-;65261:7;65281:21;65305:8;65314:4;65305:14;;;;;;;;;;;;;;;;;;;;;;;;65354;;;:8;:14;;;;;;:21;;;;;;;;;;;65305:14;;;;;;;65411:19;;;;65460:12;;:37;;;;;65305:14;;-1:-1:-1;65354:21:0;;65411:19;;65305:14;;65460:12;;;;;:22;;:37;;65491:4;;65460:37;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65441:56;;65530:4;:19;;;65512:15;:37;:54;;;;-1:-1:-1;65553:13:0;;;65512:54;65508:349;;;65583:18;65604:51;65618:4;:19;;;65639:15;65604:13;:51::i;:::-;65583:72;;65670:17;65690:70;65744:15;;65690:49;65723:4;:15;;;65690:28;65705:12;;65690:10;:14;;:28;;;;:::i;:70::-;65670:90;-1:-1:-1;65792:53:0;65811:33;65835:8;65811:19;65670:90;65825:4;65811:13;:19::i;:33::-;65792:14;;:18;:53::i;:::-;65775:70;;65508:349;;;65874:62;65920:4;:15;;;65874:41;65910:4;65874:31;65890:14;65874:4;:11;;;:15;;:31;;;;:::i;:62::-;65867:69;65189:755;-1:-1:-1;;;;;;;65189:755:0:o;61716:46::-;61758:4;61716:46;:::o;61535:22::-;;;;;;:::o;67136:656::-;67204:21;67228:8;67237:4;67228:14;;;;;;;;;;;;;;;;;;;;;;;;67277;;;:8;:14;;;;;;67292:10;67277:26;;;;;;;67228:14;;;;;;;;-1:-1:-1;67316:16:0;67286:4;67316:10;:16::i;:::-;67345:15;67363:67;67414:4;:15;;;67363:46;67404:4;67363:36;67379:4;:19;;;67363:4;:11;;;:15;;:36;;;;:::i;:67::-;67457:11;;67345:85;;-1:-1:-1;67457:24:0;;67473:7;67457:15;:24::i;:::-;67443:38;;;67526:19;;;;67510:46;;67551:4;;67510:36;;67443:38;67510:15;:36::i;:46::-;67492:15;;;:64;67572:11;;67569:79;;67600:36;67616:10;67628:7;67600:15;:36::i;:::-;67658:12;;:74;;:12;;67696:10;67717:4;67724:7;67658:29;:74::i;:::-;67770:4;67758:10;67750:34;;;67776:7;67750:34;;;;;;:::i;50144:244::-;49421:12;:10;:12::i;:::-;49410:23;;:7;:5;:7::i;:::-;:23;;;49402:68;;;;;;;;;;;;:::i;:::-;50233:22:::1;::::0;::::1;50225:73;;;;;;;;;;;;:::i;:::-;50335:6;::::0;;50314:38:::1;::::0;::::1;::::0;;::::1;::::0;50335:6;::::1;::::0;50314:38:::1;::::0;::::1;50363:6;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;50144:244::o;61771:44::-;61811:4;61771:44;:::o;21973:98::-;22053:10;21973:98;:::o;63431:269::-;63517:8;:15;63500:14;63543:148;63573:6;63566:4;:13;63543:148;;;63638:8;63612:34;;:8;63621:4;63612:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:22;;;:34;;63604:75;;;;;;;;;;;;:::i;:::-;63581:6;;;;:::i;:::-;;;;63543:148;;;;63431:269;;:::o;17144:98::-;17202:7;17229:5;17233:1;17229;:5;:::i;17882:98::-;17940:7;17967:5;17971:1;17967;:5;:::i;18281:98::-;18339:7;18366:5;18370:1;18366;:5;:::i;17525:98::-;17583:7;17610:5;17614:1;17610;:5;:::i;69149:271::-;69241:3;;:28;;;;;69224:14;;69241:3;;;:13;;:28;;69263:4;;69241:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69224:45;;69294:6;69284:7;:16;69280:133;;;69317:3;;:25;;;;;:3;;;;;:12;;:25;;69330:3;;69335:6;;69317:25;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;69280:133;;;69375:3;;:26;;;;;:3;;;;;:12;;:26;;69388:3;;69393:7;;69375:26;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;69149:271;;;:::o;11241:177::-;11324:86;11344:5;11374:23;;;11399:2;11403:5;11351:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11324:19;:86::i;11426:205::-;11527:96;11547:5;11577:27;;;11606:4;11612:2;11616:5;11554:68;;;;;;;;;;:::i;13675:761::-;14099:23;14125:69;14153:4;14125:69;;;;;;;;;;;;;;;;;14133:5;14125:27;;;;:69;;;;;:::i;:::-;14209:17;;14099:95;;-1:-1:-1;14209:21:0;14205:224;;14351:10;14340:30;;;;;;;;;;;;:::i;:::-;14332:85;;;;;;;;;;;;:::i;6374:195::-;6477:12;6509:52;6531:6;6539:4;6545:1;6548:12;6509:21;:52::i;:::-;6502:59;;6374:195;;;;;;:::o;7426:530::-;7553:12;7611:5;7586:21;:30;;7578:81;;;;;;;;;;;;:::i;:::-;7678:18;7689:6;7678:10;:18::i;:::-;7670:60;;;;;;;;;;;;:::i;:::-;7804:12;7818:23;7845:6;:11;;7865:5;7873:4;7845:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7803:75;;;;7896:52;7914:7;7923:10;7935:12;7896:17;:52::i;3456:422::-;3823:20;3862:8;;;3456:422::o;9966:742::-;10081:12;10110:7;10106:595;;;-1:-1:-1;10141:10:0;10134:17;;10106:595;10255:17;;:21;10251:439;;10518:10;10512:17;10579:15;10566:10;10562:2;10558:19;10551:44;10466:148;10661:12;10654:20;;;;;;;;;;;:::i;14:259:1:-;;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:33;237:5;210:33;:::i;278:297::-;;398:2;386:9;377:7;373:23;369:32;366:2;;;419:6;411;404:22;366:2;456:9;450:16;509:5;502:13;495:21;488:5;485:32;475:2;;536:6;528;521:22;580:190;;692:2;680:9;671:7;667:23;663:32;660:2;;;713:6;705;698:22;660:2;-1:-1:-1;741:23:1;;650:120;-1:-1:-1;650:120:1:o;775:194::-;;898:2;886:9;877:7;873:23;869:32;866:2;;;919:6;911;904:22;866:2;-1:-1:-1;947:16:1;;856:113;-1:-1:-1;856:113:1:o;974:327::-;;;1103:2;1091:9;1082:7;1078:23;1074:32;1071:2;;;1124:6;1116;1109:22;1071:2;1165:9;1152:23;1142:33;;1225:2;1214:9;1210:18;1197:32;1238:33;1265:5;1238:33;:::i;:::-;1290:5;1280:15;;;1061:240;;;;;:::o;1306:340::-;;;1448:2;1436:9;1427:7;1423:23;1419:32;1416:2;;;1469:6;1461;1454:22;1651:258;;;1780:2;1768:9;1759:7;1755:23;1751:32;1748:2;;;1801:6;1793;1786:22;1748:2;-1:-1:-1;;1829:23:1;;;1899:2;1884:18;;;1871:32;;-1:-1:-1;1738:171:1:o;1914:274::-;;2081:6;2075:13;2097:53;2143:6;2138:3;2131:4;2123:6;2119:17;2097:53;:::i;:::-;2166:16;;;;;2051:137;-1:-1:-1;;2051:137:1:o;2193:226::-;2369:42;2357:55;;;;2339:74;;2327:2;2312:18;;2294:125::o;2424:398::-;2636:42;2705:15;;;2687:34;;2757:15;;;;2752:2;2737:18;;2730:43;2804:2;2789:18;;2782:34;;;;2614:2;2599:18;;2581:241::o;2827:297::-;3031:42;3019:55;;;;3001:74;;3106:2;3091:18;;3084:34;2989:2;2974:18;;2956:168::o;3129:453::-;3403:42;3391:55;;;;3373:74;;3478:2;3463:18;;3456:34;;;;3521:2;3506:18;;3499:34;3564:2;3549:18;;3542:34;3360:3;3345:19;;3327:255::o;3838:442::-;;3987:2;3976:9;3969:21;4019:6;4013:13;4062:6;4057:2;4046:9;4042:18;4035:34;4078:66;4137:6;4132:2;4121:9;4117:18;4112:2;4104:6;4100:15;4078:66;:::i;:::-;4196:2;4184:15;4201:66;4180:88;4165:104;;;;4271:2;4161:113;;3959:321;-1:-1:-1;;3959:321:1:o;4285:402::-;4487:2;4469:21;;;4526:2;4506:18;;;4499:30;4565:34;4560:2;4545:18;;4538:62;4636:8;4631:2;4616:18;;4609:36;4677:3;4662:19;;4459:228::o;4692:355::-;4894:2;4876:21;;;4933:2;4913:18;;;4906:30;4972:33;4967:2;4952:18;;4945:61;5038:2;5023:18;;4866:181::o;5052:402::-;5254:2;5236:21;;;5293:2;5273:18;;;5266:30;5332:34;5327:2;5312:18;;5305:62;5403:8;5398:2;5383:18;;5376:36;5444:3;5429:19;;5226:228::o;5459:352::-;5661:2;5643:21;;;5700:2;5680:18;;;5673:30;5739;5734:2;5719:18;;5712:58;5802:2;5787:18;;5633:178::o;5816:332::-;6018:2;6000:21;;;6057:1;6037:18;;;6030:29;6095:11;6090:2;6075:18;;6068:39;6139:2;6124:18;;5990:158::o;6153:356::-;6355:2;6337:21;;;6374:18;;;6367:30;6433:34;6428:2;6413:18;;6406:62;6500:2;6485:18;;6327:182::o;6514:353::-;6716:2;6698:21;;;6755:2;6735:18;;;6728:30;6794:31;6789:2;6774:18;;6767:59;6858:2;6843:18;;6688:179::o;6872:342::-;7074:2;7056:21;;;7113:2;7093:18;;;7086:30;7152:20;7147:2;7132:18;;7125:48;7205:2;7190:18;;7046:168::o;7219:352::-;7421:2;7403:21;;;7460:2;7440:18;;;7433:30;7499;7494:2;7479:18;;7472:58;7562:2;7547:18;;7393:178::o;7576:406::-;7778:2;7760:21;;;7817:2;7797:18;;;7790:30;7856:34;7851:2;7836:18;;7829:62;7927:12;7922:2;7907:18;;7900:40;7972:3;7957:19;;7750:232::o;7987:177::-;8133:25;;;8121:2;8106:18;;8088:76::o;8169:248::-;8343:25;;;8399:2;8384:18;;8377:34;8331:2;8316:18;;8298:119::o;8422:128::-;;8493:1;8489:6;8486:1;8483:13;8480:2;;;8499:18;;:::i;:::-;-1:-1:-1;8535:9:1;;8470:80::o;8555:274::-;;8621:1;8611:2;;8656:77;8653:1;8646:88;8757:4;8754:1;8747:15;8785:4;8782:1;8775:15;8611:2;-1:-1:-1;8814:9:1;;8601:228::o;8834:::-;;9000:1;8932:66;8928:74;8925:1;8922:81;8917:1;8910:9;8903:17;8899:105;8896:2;;;9007:18;;:::i;:::-;-1:-1:-1;9047:9:1;;8886:176::o;9067:125::-;;9135:1;9132;9129:8;9126:2;;;9140:18;;:::i;:::-;-1:-1:-1;9177:9:1;;9116:76::o;9197:258::-;9269:1;9279:113;9293:6;9290:1;9287:13;9279:113;;;9369:11;;;9363:18;9350:11;;;9343:39;9315:2;9308:10;9279:113;;;9410:6;9407:1;9404:13;9401:2;;;-1:-1:-1;;9445:1:1;9427:16;;9420:27;9250:205::o;9460:195::-;;9530:66;9523:5;9520:77;9517:2;;;9600:18;;:::i;:::-;-1:-1:-1;9647:1:1;9636:13;;9507:148::o;9660:184::-;9712:77;9709:1;9702:88;9809:4;9806:1;9799:15;9833:4;9830:1;9823:15;9849:156;9937:42;9930:5;9926:54;9919:5;9916:65;9906:2;;9995:1;9992;9985:12
Swarm Source
ipfs://ceeaa6b250749868c1bde500eca161bac4325233457a12976ea0cb80b20145d8
Loading...
Loading
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.