Overview
ETH Balance
13.865554055355794874 ETH
Eth Value
$49,998.27 (@ $3,605.93/ETH)Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 3,731 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Buy NOM | 21273703 | 34 hrs ago | IN | 0.006 ETH | 0.00291498 | ||||
Buy NOM | 21190487 | 13 days ago | IN | 0.006 ETH | 0.00209828 | ||||
Sell NOM | 19997073 | 179 days ago | IN | 0 ETH | 0.00140463 | ||||
Sell NOM | 19953122 | 185 days ago | IN | 0 ETH | 0.00039174 | ||||
Sell NOM | 19835048 | 202 days ago | IN | 0 ETH | 0.00040358 | ||||
Sell NOM | 19834899 | 202 days ago | IN | 0 ETH | 0.00043148 | ||||
Sell NOM | 19752341 | 213 days ago | IN | 0 ETH | 0.00052992 | ||||
Sell NOM | 19741393 | 215 days ago | IN | 0 ETH | 0.00060599 | ||||
Sell NOM | 19592919 | 236 days ago | IN | 0 ETH | 0.00091297 | ||||
Sell NOM | 19584139 | 237 days ago | IN | 0 ETH | 0.00580214 | ||||
Sell NOM | 19578640 | 238 days ago | IN | 0 ETH | 0.00184456 | ||||
Sell NOM | 19571140 | 239 days ago | IN | 0 ETH | 0.00358218 | ||||
Sell NOM | 19562363 | 240 days ago | IN | 0 ETH | 0.00283075 | ||||
Sell NOM | 19447365 | 256 days ago | IN | 0 ETH | 0.00391211 | ||||
Buy NOM | 19423122 | 260 days ago | IN | 0.06 ETH | 0.00796767 | ||||
Sell NOM | 19400749 | 263 days ago | IN | 0 ETH | 0.00464457 | ||||
Sell NOM | 19390968 | 264 days ago | IN | 0 ETH | 0.00654093 | ||||
Sell NOM | 19266478 | 282 days ago | IN | 0 ETH | 0.00322592 | ||||
Sell NOM | 19206303 | 290 days ago | IN | 0 ETH | 0.00205905 | ||||
Sell NOM | 19018213 | 316 days ago | IN | 0 ETH | 0.00375166 | ||||
Sell NOM | 18983337 | 321 days ago | IN | 0 ETH | 0.00186793 | ||||
Sell NOM | 18858490 | 339 days ago | IN | 0 ETH | 0.00145133 | ||||
Buy NOM | 18844333 | 341 days ago | IN | 0.05 ETH | 0.00246061 | ||||
Buy NOM | 18810630 | 345 days ago | IN | 0.1 ETH | 0.00609041 | ||||
Sell NOM | 18736731 | 356 days ago | IN | 0 ETH | 0.00477835 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
19997073 | 179 days ago | 0.32058246 ETH | ||||
19953122 | 185 days ago | 0.28965387 ETH | ||||
19835048 | 202 days ago | 0.05138079 ETH | ||||
19834899 | 202 days ago | 2.86688509 ETH | ||||
19752341 | 213 days ago | 2.82014336 ETH | ||||
19741393 | 215 days ago | 2.8289234 ETH | ||||
19592919 | 236 days ago | 0.00786401 ETH | ||||
19584139 | 237 days ago | 0.08523095 ETH | ||||
19578640 | 238 days ago | 0.00714077 ETH | ||||
19571140 | 239 days ago | 1.03479192 ETH | ||||
19562363 | 240 days ago | 0.30937871 ETH | ||||
19447365 | 256 days ago | 0.0396399 ETH | ||||
19400749 | 263 days ago | 0.06937814 ETH | ||||
19390968 | 264 days ago | 0.0969109 ETH | ||||
19266478 | 282 days ago | 0.26100607 ETH | ||||
19206303 | 290 days ago | 0.01844437 ETH | ||||
19018213 | 316 days ago | 0.13972022 ETH | ||||
18983337 | 321 days ago | 0.26331997 ETH | ||||
18858490 | 339 days ago | 0.09801524 ETH | ||||
18736731 | 356 days ago | 0.28182408 ETH | ||||
18736531 | 356 days ago | 0.45814189 ETH | ||||
18719708 | 358 days ago | 0.28411571 ETH | ||||
18665441 | 366 days ago | 0.75550084 ETH | ||||
18649835 | 368 days ago | 0.02348791 ETH | ||||
18649796 | 368 days ago | 0.23588928 ETH |
Loading...
Loading
Contract Name:
BondingNOM
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts/token/ERC20/ERC20Burnable.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "abdk-libraries-solidity/ABDKMath64x64.sol"; interface ERC20Token { function allowance(address, address) external returns (uint256); function balanceOf(address) external returns (uint256); function totalSupply() external view returns (uint256); function transferFrom(address, address, uint256) external returns (bool); function transfer(address, uint256) external returns (bool); } /// @title bNOM Bonding Contract contract BondingNOM is Ownable { ERC20Token nc; using SafeMath for uint256; /// @notice Address of the nc (NOM ERC20 Contract) address public NOMTokenContract; uint256 public supplyNOM = 0; uint256 public priceBondCurve = 0; uint8 public decimals = 18; uint256 public a = SafeMath.mul(100000000, 10**decimals); bool public tradingEnabled = false; event Transaction(address indexed _by, uint256 amountNOM, uint256 amountETH, uint256 price, uint256 supply, string buyOrSell, int256 slippage); constructor (address NOMContAddr) { // Add in the NOM ERC20 contract address NOMTokenContract = NOMContAddr; nc = ERC20Token(NOMContAddr); } /// @return Return the bool value which indicates whether the trading is enabled. function getTradingEnabled() public view returns (bool) { return tradingEnabled; } /// @notice Return the NOM Token Contract address function getNOMAddr() public view returns (address) { return NOMTokenContract; } /// @return Return the NOM Token circulate supply function getSupplyNOM() public view returns (uint256) { return supplyNOM; } /// @return Return the price based on current NOM supply function getBondPrice() public view returns (uint256) { return priceBondCurve; } /// @param token uint256 token amount /// @return Return token amount to F64(Fixed Point 64) format /// @notice This function will use `ABDKMath64x64.divu` module from `abdk-libraries-solidity` library function tokToF64(uint256 token) public view returns(int128) { return ABDKMath64x64.divu(token, 10**uint256(decimals)); } /// @return Return F64(Fixed Point 64) token amount to uint256 /// @notice This function will use `ABDKMath64x64.mulu` module from `abdk-libraries-solidity` library function f64ToTok(int128 fixed64) public view returns(uint256) { return ABDKMath64x64.mulu(fixed64, 10**uint256(decimals)); } /// @return Return the amount of burned bNOM /// @notice Formula: totalSupply[initial] - totalSupply[now] function burnedNOM() public view returns(uint256) { return a.sub(nc.totalSupply()); } /// @return Return the token price base on the input supply amount /// @param _supplyNOM token supply amount in uint256 /// @notice Formula: `ETH/NOM = pow(_supplyNOM/a, 2)` Using this function, everyone can predict the exact price base on token supply function priceAtSupply(uint256 _supplyNOM) public view returns(uint256) { if (_supplyNOM == 0) return 0; require(_supplyNOM <= a, "Bonding Curve terminates below bNOM amount input"); return f64ToTok( ABDKMath64x64.pow( ABDKMath64x64.div( tokToF64(_supplyNOM), tokToF64(a) ), uint256(2) ) ); } /// @return Return token supply amount for input price /// @param price F64(Fixed Point 64) formated amount /// @notice Formula: `_suppliedNom = sqrt(ETH/NOM) * a` Using this function, everyone can predict the exact token supply base on token price function supplyAtPrice(uint256 price) public view returns (uint256) { if (price == 0) return 0; require(price <= 10**18, "Bonding Curve terminates below ETH/bNOM price input"); return f64ToTok( ABDKMath64x64.mul( ABDKMath64x64.sqrt( tokToF64(price) ), tokToF64(a) ) ); } /// @return Return NOM supply range to ETH /// @param supplyTop NOM supply top amount /// @param supplyBot NOM supply bottom amount /// @notice Formula: `ETH = a/3((supplyNOM_Top/a)^3 - (supplyNOM_Bot/a)^3)` /// Integrate over a curve to get the amount of ETH needed to buy the amount of NOM function NOMSupToETH(uint256 supplyTop, uint256 supplyBot) public view returns(uint256) { if (supplyTop - supplyBot == 0) return 0; require(supplyTop > supplyBot, "Supply Bot greater than Supply Top"); require(supplyTop <= a, "Supply Top greater than initial supply of bNOM"); require(supplyTop.sub(supplyBot) <= a.sub(supplyNOM), "Request greater than the bonded supply of bNOM"); return f64ToTok( ABDKMath64x64.mul( // a/3 ABDKMath64x64.div( tokToF64(a), ABDKMath64x64.fromUInt(uint256(3)) ), // ((NomSold_Top/a)^3 - (supplyNOM_Bot/a)^3) ABDKMath64x64.sub( // (NomSold_Top/a)^3 ABDKMath64x64.pow( ABDKMath64x64.div( tokToF64(supplyTop), tokToF64(a) ), uint256(3) ), // (NomSold_Bot/a)^3 ABDKMath64x64.pow( ABDKMath64x64.div( tokToF64(supplyBot), tokToF64(a) ), uint256(3) ) ) ) ); } /// @return Return quote for a particular amount of NOM (Dec 18) in ETH (Dec 18) /// @param amountNOM amount of NOM to be purchased in 18 decimal /// @notice 1. Determine supply range based on spread and current curve price based on supplyNOM /// 2. Integrate over curve to get amount of ETH needed to buy amount of NOM /// ETH = a/3((supplyNOM_Top/a)^3 - (supplyNOM_Bot/a)^3) /// Parameters: /// Input /// uint256 buyAmount: amount of NOM to be purchased in 18 decimal /// Output /// uint256: amount of ETH needed in Wei or ETH 18 decimal function buyQuoteNOM(uint256 amountNOM) public view returns(uint256) { if (amountNOM == 0) return 0; require(amountNOM <= a.sub(supplyNOM), "Sell amount of bNOM greater than unbonded amount of bNOM"); uint256 supplyTop = supplyNOM.add(amountNOM); uint256 amountETH = NOMSupToETH(supplyTop, supplyNOM); return amountETH.sub(amountETH.div(100)); } /// @return Return cubrtu(x) rounding down, where x is unsigned 256-bit integer /// @param x unsigned 256-bit integer number function cubrtu (uint256 x) public pure returns (uint256) { if (x == 0) return 0; else { uint256 xx = x; uint256 r = 1; if (xx >= 0x1000000000000000000000000000000000000) {xx >>= 144; r <<= 48;} if (xx >= 0x1000000000000000000) {xx >>= 72; r <<= 24;} if (xx >= 0x1000000000) {xx >>= 36; r <<= 12;} if (xx >= 0x40000) {xx >>= 18; r <<= 6;} if (xx >= 0x1000) {xx >>= 12; r <<= 4;} if (xx >= 0x200) {xx >>= 9; r <<= 3;} if (xx >= 0x40) {xx >>= 6; r <<= 2;} if (xx >= 0x8) {r <<= 1;} r = (x/(r**2) + 2*r)/3; r = (x/(r**2) + 2*r)/3; r = (x/(r**2) + 2*r)/3; r = (x/(r**2) + 2*r)/3; r = (x/(r**2) + 2*r)/3; r = (x/(r**2) + 2*r)/3; r = (x/(r**2) + 2*r)/3; // Seven iterations should be enough return r; } } /// @param amountETH amoutt of ETH /// @return Buy Quote for the purchase of NOM based on amount of ETH (Dec 18) /// @notice 1. Determine supply bottom /// 2. Integrate over curve, and solve for supply top supplyNOM_Top = a*(3*ETH/a + (supplyNOM_Bot/a)^3)^(1/3) /// 3. Subtract supply bottom from top to get #NOM for ETH function buyQuoteETH(uint256 amountETH) public view returns(uint256) { if (amountETH == 0) return 0; uint256 amountNet = amountETH.sub(amountETH.div(100)); uint256 supplyTop = // supplyNOM_Top = (a^2*(3*ETH + (supplyNOM_Bot/a)^2*supplyNOM_Bot))^(1/3) cubrtu( SafeMath.mul( // a^2 a.mul(a), // (3*ETH + (supplyNOM_Bot/a)^2*supplyNOM_Bot) f64ToTok( ABDKMath64x64.add( ABDKMath64x64.mul( ABDKMath64x64.fromUInt(uint256(3)), tokToF64(amountNet) ), ABDKMath64x64.mul( ABDKMath64x64.pow( ABDKMath64x64.div( tokToF64(supplyNOM), tokToF64(a) ), uint256(2) ), tokToF64(supplyNOM) ) ) ) ) ); require(supplyTop <= a, "Supply Top greater than initial supply"); return supplyTop - supplyNOM; } function abs(int128 x) private pure returns (int128) { return x >= 0 ? x : -x; } /// @param estAmountNOM amount of NOM /// @param allowSlip amount of slippage allowed in 0100 means 1% function buyNOM(uint256 estAmountNOM, uint256 allowSlip) public payable { require(tradingEnabled, "The trading is disabled"); require(msg.value > 0, "Amount ETH sent with request equal to zero"); require(estAmountNOM <= (a.sub(supplyNOM)), "Estimated amount of bNOM greater bonded supply of bNOM"); uint256 amountNOM = buyQuoteETH(msg.value); // Positive slippage is bad. Negative slippage is good. // Positive slippage means we will receive less NOM than estimated if(estAmountNOM > amountNOM) { require( // Slippage estAmountNOM.sub(amountNOM) < // Allowed slippage estAmountNOM.div(10000).mul(allowSlip) , "Slippage greater than allowed" ); } int256 slippage = int256(estAmountNOM) - int256(amountNOM); // Update total supply released by Bonding Curve supplyNOM = supplyNOM.add(amountNOM); // Update current bond curve price priceBondCurve = priceAtSupply(supplyNOM); nc.transfer(msg.sender, amountNOM); emit Transaction(msg.sender, amountNOM, msg.value, priceBondCurve, supplyNOM, "buy", slippage); } /// @param amountNOM amount of NOM /// @return Return Sell Quote: NOM for ETH (Dec 18) /// @notice 1. Determine supply top: priceBondCurve - 1% = Top Sale Price /// 2. Integrate over curve to find ETH: `ETH = a/3((supplyNOM_Top/a)^3 - (supplyNOM_Bot/a)^3)` /// 3. Subtract supply bottom from top to get #NOM for ETH function sellQuoteNOM(uint256 amountNOM) public view returns(uint256) { if (amountNOM == 0) return 0; require(amountNOM <= (supplyNOM - burnedNOM()), "Sell amount of bNOM greater than unbonded amount of bNOM"); uint256 supplyBot = supplyNOM.sub(amountNOM); uint256 amountETH = NOMSupToETH(supplyNOM, supplyBot); return amountETH.sub(amountETH.div(100)); } /// @param amountNOM amount of NOM /// @param estAmountETH estimation of ETH amount /// @param allowSlip is a percentage represented as an percentage * 10^2 with a 2 decimal fixed point /// 1% would be uint256 representation of 0100, 1.25% would be 0125, 25.5% would be 2550 /// @notice Transfer ETH worth amount of NOM to msg.sender function sellNOM(uint256 amountNOM, uint256 estAmountETH, uint256 allowSlip) public payable { require(amountNOM > 0, "Sell amount of bNOM equal to zero"); require(amountNOM <= (supplyNOM - burnedNOM()), "Sell amount of bNOM greater than unbonded amount of bNOM"); require(amountNOM <= nc.allowance(msg.sender, address(this)), "Insufficient Bond Contract bNOM allowance"); uint256 amountETH = sellQuoteNOM(amountNOM); // Positive slippage is bad. Negative slippage is good. // Positive slippage means we will receive less NOM than estimated if(estAmountETH > amountETH) { require( // Slippage estAmountETH.sub(amountETH) < estAmountETH.div(10000).mul(allowSlip), "Slippage greater than allowed" ); } int256 slippage = int256(estAmountETH) - int256(amountETH); // Transfer NOM to contract nc.transferFrom(msg.sender, address(this), amountNOM); // Update persistent contract state variables // Update total supply released by Bonding Curve supplyNOM = supplyNOM.sub(amountNOM); // Update current bond curve price priceBondCurve = priceAtSupply(supplyNOM); emit Transaction(msg.sender, amountNOM, amountETH, priceBondCurve, supplyNOM, "sell", slippage); // Transfer ETH to Sender payable(msg.sender).transfer(amountETH); } /// @return Teambalance in ETH /// @notice 1. Calculate amount ETH to cover all current NOM outstanding based on bonding curve integration. /// 2. Subtraction lockedETH from Contract Balance to get amount available for withdrawal. function teamBalance() public view returns(uint256) { if (supplyNOM == 0) { return address(this).balance; } uint256 lockedETH = NOMSupToETH(supplyNOM, burnedNOM()); return address(this).balance.sub(lockedETH); } /// @notice 1. Calculate amount ETH to cover all current NOM outstanding based on bonding curve integration. /// 2. Subtraction lockedETH from Contract Balance to get amount available for withdrawal. function withdraw() public onlyOwner returns(bool success) { if (supplyNOM == 0) { payable(msg.sender).transfer(address(this).balance); return true; } uint256 lockedETH = NOMSupToETH(supplyNOM, burnedNOM()); uint256 paymentETH = address(this).balance.sub(lockedETH); // Transfer ETH to Owner payable(msg.sender).transfer(paymentETH); return true; } /// @notice Enables trading. function enableTrading() public onlyOwner { tradingEnabled = true; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../../utils/Context.sol"; import "./ERC20.sol"; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { using SafeMath for uint256; /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance"); _approve(account, _msgSender(), decreasedAllowance); _burn(account, amount); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { 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) { 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) { // 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) { 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) { 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) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); 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) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); 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) { require(b > 0, "SafeMath: modulo by zero"); 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) { 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. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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) { 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) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/Context.sol"; /** * @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 () internal { 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; } }
// SPDX-License-Identifier: BSD-4-Clause /* * ABDK Math 64.64 Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.5.0 || ^0.6.0 || ^0.7.0; /** * Smart contract library of mathematical functions operating with signed * 64.64-bit fixed point numbers. Signed 64.64-bit fixed point number is * basically a simple fraction whose numerator is signed 128-bit integer and * denominator is 2^64. As long as denominator is always the same, there is no * need to store it, thus in Solidity signed 64.64-bit fixed point numbers are * represented by int128 type holding only the numerator. */ library ABDKMath64x64 { /* * Minimum value signed 64.64-bit fixed point number may have. */ int128 private constant MIN_64x64 = -0x80000000000000000000000000000000; /* * Maximum value signed 64.64-bit fixed point number may have. */ int128 private constant MAX_64x64 = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; /** * Convert signed 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x signed 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromInt (int256 x) internal pure returns (int128) { require (x >= -0x8000000000000000 && x <= 0x7FFFFFFFFFFFFFFF); return int128 (x << 64); } /** * Convert signed 64.64 fixed point number into signed 64-bit integer number * rounding down. * * @param x signed 64.64-bit fixed point number * @return signed 64-bit integer number */ function toInt (int128 x) internal pure returns (int64) { return int64 (x >> 64); } /** * Convert unsigned 256-bit integer number into signed 64.64-bit fixed point * number. Revert on overflow. * * @param x unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function fromUInt (uint256 x) internal pure returns (int128) { require (x <= 0x7FFFFFFFFFFFFFFF); return int128 (x << 64); } /** * Convert signed 64.64 fixed point number into unsigned 64-bit integer * number rounding down. Revert on underflow. * * @param x signed 64.64-bit fixed point number * @return unsigned 64-bit integer number */ function toUInt (int128 x) internal pure returns (uint64) { require (x >= 0); return uint64 (x >> 64); } /** * Convert signed 128.128 fixed point number into signed 64.64-bit fixed point * number rounding down. Revert on overflow. * * @param x signed 128.128-bin fixed point number * @return signed 64.64-bit fixed point number */ function from128x128 (int256 x) internal pure returns (int128) { int256 result = x >> 64; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Convert signed 64.64 fixed point number into signed 128.128 fixed point * number. * * @param x signed 64.64-bit fixed point number * @return signed 128.128 fixed point number */ function to128x128 (int128 x) internal pure returns (int256) { return int256 (x) << 64; } /** * Calculate x + y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function add (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) + y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x - y. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function sub (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) - y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x * y rounding down. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function mul (int128 x, int128 y) internal pure returns (int128) { int256 result = int256(x) * y >> 64; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x * y rounding towards zero, where x is signed 64.64 fixed point * number and y is signed 256-bit integer number. Revert on overflow. * * @param x signed 64.64 fixed point number * @param y signed 256-bit integer number * @return signed 256-bit integer number */ function muli (int128 x, int256 y) internal pure returns (int256) { if (x == MIN_64x64) { require (y >= -0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF && y <= 0x1000000000000000000000000000000000000000000000000); return -y << 63; } else { bool negativeResult = false; if (x < 0) { x = -x; negativeResult = true; } if (y < 0) { y = -y; // We rely on overflow behavior here negativeResult = !negativeResult; } uint256 absoluteResult = mulu (x, uint256 (y)); if (negativeResult) { require (absoluteResult <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (absoluteResult); } } } /** * Calculate x * y rounding down, where x is signed 64.64 fixed point number * and y is unsigned 256-bit integer number. Revert on overflow. * * @param x signed 64.64 fixed point number * @param y unsigned 256-bit integer number * @return unsigned 256-bit integer number */ function mulu (int128 x, uint256 y) internal pure returns (uint256) { if (y == 0) return 0; require (x >= 0); uint256 lo = (uint256 (x) * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) >> 64; uint256 hi = uint256 (x) * (y >> 128); require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); hi <<= 64; require (hi <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - lo); return hi + lo; } /** * Calculate x / y rounding towards zero. Revert on overflow or when y is * zero. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function div (int128 x, int128 y) internal pure returns (int128) { require (y != 0); int256 result = (int256 (x) << 64) / y; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate x / y rounding towards zero, where x and y are signed 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x signed 256-bit integer number * @param y signed 256-bit integer number * @return signed 64.64-bit fixed point number */ function divi (int256 x, int256 y) internal pure returns (int128) { require (y != 0); bool negativeResult = false; if (x < 0) { x = -x; // We rely on overflow behavior here negativeResult = true; } if (y < 0) { y = -y; // We rely on overflow behavior here negativeResult = !negativeResult; } uint128 absoluteResult = divuu (uint256 (x), uint256 (y)); if (negativeResult) { require (absoluteResult <= 0x80000000000000000000000000000000); return -int128 (absoluteResult); // We rely on overflow behavior here } else { require (absoluteResult <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (absoluteResult); // We rely on overflow behavior here } } /** * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x unsigned 256-bit integer number * @param y unsigned 256-bit integer number * @return signed 64.64-bit fixed point number */ function divu (uint256 x, uint256 y) internal pure returns (int128) { require (y != 0); uint128 result = divuu (x, y); require (result <= uint128 (MAX_64x64)); return int128 (result); } /** * Calculate -x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function neg (int128 x) internal pure returns (int128) { require (x != MIN_64x64); return -x; } /** * Calculate |x|. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function abs (int128 x) internal pure returns (int128) { require (x != MIN_64x64); return x < 0 ? -x : x; } /** * Calculate 1 / x rounding towards zero. Revert on overflow or when x is * zero. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function inv (int128 x) internal pure returns (int128) { require (x != 0); int256 result = int256 (0x100000000000000000000000000000000) / x; require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate arithmetics average of x and y, i.e. (x + y) / 2 rounding down. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function avg (int128 x, int128 y) internal pure returns (int128) { return int128 ((int256 (x) + int256 (y)) >> 1); } /** * Calculate geometric average of x and y, i.e. sqrt (x * y) rounding down. * Revert on overflow or in case x * y is negative. * * @param x signed 64.64-bit fixed point number * @param y signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function gavg (int128 x, int128 y) internal pure returns (int128) { int256 m = int256 (x) * int256 (y); require (m >= 0); require (m < 0x4000000000000000000000000000000000000000000000000000000000000000); return int128 (sqrtu (uint256 (m))); } /** * Calculate x^y assuming 0^0 is 1, where x is signed 64.64 fixed point number * and y is unsigned 256-bit integer number. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @param y uint256 value * @return signed 64.64-bit fixed point number */ function pow (int128 x, uint256 y) internal pure returns (int128) { bool negative = x < 0 && y & 1 == 1; uint256 absX = uint128 (x < 0 ? -x : x); uint256 absResult; absResult = 0x100000000000000000000000000000000; if (absX <= 0x10000000000000000) { absX <<= 63; while (y != 0) { if (y & 0x1 != 0) { absResult = absResult * absX >> 127; } absX = absX * absX >> 127; if (y & 0x2 != 0) { absResult = absResult * absX >> 127; } absX = absX * absX >> 127; if (y & 0x4 != 0) { absResult = absResult * absX >> 127; } absX = absX * absX >> 127; if (y & 0x8 != 0) { absResult = absResult * absX >> 127; } absX = absX * absX >> 127; y >>= 4; } absResult >>= 64; } else { uint256 absXShift = 63; if (absX < 0x1000000000000000000000000) { absX <<= 32; absXShift -= 32; } if (absX < 0x10000000000000000000000000000) { absX <<= 16; absXShift -= 16; } if (absX < 0x1000000000000000000000000000000) { absX <<= 8; absXShift -= 8; } if (absX < 0x10000000000000000000000000000000) { absX <<= 4; absXShift -= 4; } if (absX < 0x40000000000000000000000000000000) { absX <<= 2; absXShift -= 2; } if (absX < 0x80000000000000000000000000000000) { absX <<= 1; absXShift -= 1; } uint256 resultShift = 0; while (y != 0) { require (absXShift < 64); if (y & 0x1 != 0) { absResult = absResult * absX >> 127; resultShift += absXShift; if (absResult > 0x100000000000000000000000000000000) { absResult >>= 1; resultShift += 1; } } absX = absX * absX >> 127; absXShift <<= 1; if (absX >= 0x100000000000000000000000000000000) { absX >>= 1; absXShift += 1; } y >>= 1; } require (resultShift < 64); absResult >>= 64 - resultShift; } int256 result = negative ? -int256 (absResult) : int256 (absResult); require (result >= MIN_64x64 && result <= MAX_64x64); return int128 (result); } /** * Calculate sqrt (x) rounding down. Revert if x < 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function sqrt (int128 x) internal pure returns (int128) { require (x >= 0); return int128 (sqrtu (uint256 (x) << 64)); } /** * Calculate binary logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function log_2 (int128 x) internal pure returns (int128) { require (x > 0); int256 msb = 0; int256 xc = x; if (xc >= 0x10000000000000000) { xc >>= 64; msb += 64; } if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore int256 result = msb - 64 << 64; uint256 ux = uint256 (x) << uint256 (127 - msb); for (int256 bit = 0x8000000000000000; bit > 0; bit >>= 1) { ux *= ux; uint256 b = ux >> 255; ux >>= 127 + b; result += bit * int256 (b); } return int128 (result); } /** * Calculate natural logarithm of x. Revert if x <= 0. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function ln (int128 x) internal pure returns (int128) { require (x > 0); return int128 ( uint256 (log_2 (x)) * 0xB17217F7D1CF79ABC9E3B39803F2F6AF >> 128); } /** * Calculate binary exponent of x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function exp_2 (int128 x) internal pure returns (int128) { require (x < 0x400000000000000000); // Overflow if (x < -0x400000000000000000) return 0; // Underflow uint256 result = 0x80000000000000000000000000000000; if (x & 0x8000000000000000 > 0) result = result * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; if (x & 0x4000000000000000 > 0) result = result * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; if (x & 0x2000000000000000 > 0) result = result * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; if (x & 0x1000000000000000 > 0) result = result * 0x10B5586CF9890F6298B92B71842A98363 >> 128; if (x & 0x800000000000000 > 0) result = result * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; if (x & 0x400000000000000 > 0) result = result * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; if (x & 0x200000000000000 > 0) result = result * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; if (x & 0x100000000000000 > 0) result = result * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; if (x & 0x80000000000000 > 0) result = result * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; if (x & 0x40000000000000 > 0) result = result * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; if (x & 0x20000000000000 > 0) result = result * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; if (x & 0x10000000000000 > 0) result = result * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; if (x & 0x8000000000000 > 0) result = result * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; if (x & 0x4000000000000 > 0) result = result * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; if (x & 0x2000000000000 > 0) result = result * 0x1000162E525EE054754457D5995292026 >> 128; if (x & 0x1000000000000 > 0) result = result * 0x10000B17255775C040618BF4A4ADE83FC >> 128; if (x & 0x800000000000 > 0) result = result * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; if (x & 0x400000000000 > 0) result = result * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; if (x & 0x200000000000 > 0) result = result * 0x10000162E43F4F831060E02D839A9D16D >> 128; if (x & 0x100000000000 > 0) result = result * 0x100000B1721BCFC99D9F890EA06911763 >> 128; if (x & 0x80000000000 > 0) result = result * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; if (x & 0x40000000000 > 0) result = result * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; if (x & 0x20000000000 > 0) result = result * 0x100000162E430E5A18F6119E3C02282A5 >> 128; if (x & 0x10000000000 > 0) result = result * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; if (x & 0x8000000000 > 0) result = result * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; if (x & 0x4000000000 > 0) result = result * 0x10000002C5C8601CC6B9E94213C72737A >> 128; if (x & 0x2000000000 > 0) result = result * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; if (x & 0x1000000000 > 0) result = result * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; if (x & 0x800000000 > 0) result = result * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; if (x & 0x400000000 > 0) result = result * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; if (x & 0x200000000 > 0) result = result * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; if (x & 0x100000000 > 0) result = result * 0x100000000B17217F80F4EF5AADDA45554 >> 128; if (x & 0x80000000 > 0) result = result * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; if (x & 0x40000000 > 0) result = result * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; if (x & 0x20000000 > 0) result = result * 0x100000000162E42FEFB2FED257559BDAA >> 128; if (x & 0x10000000 > 0) result = result * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; if (x & 0x8000000 > 0) result = result * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; if (x & 0x4000000 > 0) result = result * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; if (x & 0x2000000 > 0) result = result * 0x1000000000162E42FEFA494F1478FDE05 >> 128; if (x & 0x1000000 > 0) result = result * 0x10000000000B17217F7D20CF927C8E94C >> 128; if (x & 0x800000 > 0) result = result * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; if (x & 0x400000 > 0) result = result * 0x100000000002C5C85FDF477B662B26945 >> 128; if (x & 0x200000 > 0) result = result * 0x10000000000162E42FEFA3AE53369388C >> 128; if (x & 0x100000 > 0) result = result * 0x100000000000B17217F7D1D351A389D40 >> 128; if (x & 0x80000 > 0) result = result * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; if (x & 0x40000 > 0) result = result * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; if (x & 0x20000 > 0) result = result * 0x100000000000162E42FEFA39FE95583C2 >> 128; if (x & 0x10000 > 0) result = result * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; if (x & 0x8000 > 0) result = result * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; if (x & 0x4000 > 0) result = result * 0x10000000000002C5C85FDF473E242EA38 >> 128; if (x & 0x2000 > 0) result = result * 0x1000000000000162E42FEFA39F02B772C >> 128; if (x & 0x1000 > 0) result = result * 0x10000000000000B17217F7D1CF7D83C1A >> 128; if (x & 0x800 > 0) result = result * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; if (x & 0x400 > 0) result = result * 0x100000000000002C5C85FDF473DEA871F >> 128; if (x & 0x200 > 0) result = result * 0x10000000000000162E42FEFA39EF44D91 >> 128; if (x & 0x100 > 0) result = result * 0x100000000000000B17217F7D1CF79E949 >> 128; if (x & 0x80 > 0) result = result * 0x10000000000000058B90BFBE8E7BCE544 >> 128; if (x & 0x40 > 0) result = result * 0x1000000000000002C5C85FDF473DE6ECA >> 128; if (x & 0x20 > 0) result = result * 0x100000000000000162E42FEFA39EF366F >> 128; if (x & 0x10 > 0) result = result * 0x1000000000000000B17217F7D1CF79AFA >> 128; if (x & 0x8 > 0) result = result * 0x100000000000000058B90BFBE8E7BCD6D >> 128; if (x & 0x4 > 0) result = result * 0x10000000000000002C5C85FDF473DE6B2 >> 128; if (x & 0x2 > 0) result = result * 0x1000000000000000162E42FEFA39EF358 >> 128; if (x & 0x1 > 0) result = result * 0x10000000000000000B17217F7D1CF79AB >> 128; result >>= uint256 (63 - (x >> 64)); require (result <= uint256 (MAX_64x64)); return int128 (result); } /** * Calculate natural exponent of x. Revert on overflow. * * @param x signed 64.64-bit fixed point number * @return signed 64.64-bit fixed point number */ function exp (int128 x) internal pure returns (int128) { require (x < 0x400000000000000000); // Overflow if (x < -0x400000000000000000) return 0; // Underflow return exp_2 ( int128 (int256 (x) * 0x171547652B82FE1777D0FFDA0D23A7D12 >> 128)); } /** * Calculate x / y rounding towards zero, where x and y are unsigned 256-bit * integer numbers. Revert on overflow or when y is zero. * * @param x unsigned 256-bit integer number * @param y unsigned 256-bit integer number * @return unsigned 64.64-bit fixed point number */ function divuu (uint256 x, uint256 y) private pure returns (uint128) { require (y != 0); uint256 result; if (x <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) result = (x << 64) / y; else { uint256 msb = 192; uint256 xc = x >> 192; if (xc >= 0x100000000) { xc >>= 32; msb += 32; } if (xc >= 0x10000) { xc >>= 16; msb += 16; } if (xc >= 0x100) { xc >>= 8; msb += 8; } if (xc >= 0x10) { xc >>= 4; msb += 4; } if (xc >= 0x4) { xc >>= 2; msb += 2; } if (xc >= 0x2) msb += 1; // No need to shift xc anymore result = (x << 255 - msb) / ((y - 1 >> msb - 191) + 1); require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint256 hi = result * (y >> 128); uint256 lo = result * (y & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); uint256 xh = x >> 192; uint256 xl = x << 64; if (xl < lo) xh -= 1; xl -= lo; // We rely on overflow behavior here lo = hi << 128; if (xl < lo) xh -= 1; xl -= lo; // We rely on overflow behavior here assert (xh == hi >> 128); result += xl / y; } require (result <= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return uint128 (result); } /** * Calculate sqrt (x) rounding down, where x is unsigned 256-bit integer * number. * * @param x unsigned 256-bit integer number * @return unsigned 128-bit integer number */ function sqrtu (uint256 x) private pure returns (uint128) { if (x == 0) return 0; else { uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; // Seven iterations should be enough uint256 r1 = x / r; return uint128 (r < r1 ? r : r1); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../../utils/Context.sol"; import "./IERC20.sol"; import "../../math/SafeMath.sol"; /** * @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 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name_, string memory symbol_) public { _name = name_; _symbol = symbol_; _decimals = 18; } /** * @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 {_setupDecimals} is * called. * * 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 _decimals; } /** * @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); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); 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].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); 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); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(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); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(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 Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal virtual { _decimals = decimals_; } /** * @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 { } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"NOMContAddr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"_by","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountNOM","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountETH","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"},{"indexed":false,"internalType":"string","name":"buyOrSell","type":"string"},{"indexed":false,"internalType":"int256","name":"slippage","type":"int256"}],"name":"Transaction","type":"event"},{"inputs":[{"internalType":"uint256","name":"supplyTop","type":"uint256"},{"internalType":"uint256","name":"supplyBot","type":"uint256"}],"name":"NOMSupToETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NOMTokenContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"a","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnedNOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"estAmountNOM","type":"uint256"},{"internalType":"uint256","name":"allowSlip","type":"uint256"}],"name":"buyNOM","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"name":"buyQuoteETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountNOM","type":"uint256"}],"name":"buyQuoteNOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"x","type":"uint256"}],"name":"cubrtu","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int128","name":"fixed64","type":"int128"}],"name":"f64ToTok","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBondPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNOMAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSupplyNOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTradingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_supplyNOM","type":"uint256"}],"name":"priceAtSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceBondCurve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountNOM","type":"uint256"},{"internalType":"uint256","name":"estAmountETH","type":"uint256"},{"internalType":"uint256","name":"allowSlip","type":"uint256"}],"name":"sellNOM","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountNOM","type":"uint256"}],"name":"sellQuoteNOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"supplyAtPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyNOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"teamBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"token","type":"uint256"}],"name":"tokToF64","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052600060035560006004556012600560006101000a81548160ff021916908360ff1602179055506200005a6305f5e100600560009054906101000a900460ff1660ff16600a0a620001f560201b6200207b1760201c565b6006556000600760006101000a81548160ff0219169083151502179055503480156200008557600080fd5b506040516200313a3803806200313a83398181016040526020811015620000ab57600080fd5b81019080805190602001909291905050506000620000ce6200028060201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505062000288565b6000808314156200020a57600090506200027a565b60008284029050828482816200021c57fe5b041462000275576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180620031196021913960400191505060405180910390fd5b809150505b92915050565b600033905090565b612e8180620002986000396000f3fe6080604052600436106101b65760003560e01c806359eaced0116100ec5780638e117f6d1161008a578063daff394a11610064578063daff394a14610721578063eb208d6f14610770578063f2fde38b146107b2578063fa83cb5814610803576101b6565b80638e117f6d14610672578063afea58521461069d578063bc0f023c146106f6576101b6565b80637eda9347116100c65780637eda9347146105c457806389e85217146105ef5780638a8c523c1461061a5780638da5cb5b14610631576101b6565b806359eaced01461051d578063715018a61461055e5780637abe744814610575576101b6565b8063313ce567116101595780633ccfd60b116101335780633ccfd60b146104465780634477392b146104735780634ada218b1461049e5780635700f200146104cb576101b6565b8063313ce567146103ac5780633542a097146103da5780633c4df4fc1461041b576101b6565b80630dbe671f116101955780630dbe671f1461029157806325572aa4146102bc578063289044751461030b57806329b57f881461035a576101b6565b80627f39c7146101bb57806302689ad61461020a578063080d1f8214610259575b600080fd5b3480156101c757600080fd5b506101f4600480360360208110156101de57600080fd5b8101908080359060200190929190505050610830565b6040518082815260200191505060405180910390f35b34801561021657600080fd5b506102436004803603602081101561022d57600080fd5b81019080803590602001909291905050506109ff565b6040518082815260200191505060405180910390f35b61028f6004803603604081101561026f57600080fd5b810190808035906020019092919080359060200190929190505050610acf565b005b34801561029d57600080fd5b506102a6610e8f565b6040518082815260200191505060405180910390f35b3480156102c857600080fd5b506102f5600480360360208110156102df57600080fd5b8101908080359060200190929190505050610e95565b6040518082815260200191505060405180910390f35b34801561031757600080fd5b506103446004803603602081101561032e57600080fd5b8101908080359060200190929190505050610f3d565b6040518082815260200191505060405180910390f35b34801561036657600080fd5b506103936004803603602081101561037d57600080fd5b8101908080359060200190929190505050611018565b6040518082600f0b815260200191505060405180910390f35b3480156103b857600080fd5b506103c1611040565b604051808260ff16815260200191505060405180910390f35b3480156103e657600080fd5b506103ef611053565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561042757600080fd5b50610430611079565b6040518082815260200191505060405180910390f35b34801561045257600080fd5b5061045b61107f565b60405180821515815260200191505060405180910390f35b34801561047f57600080fd5b5061048861120a565b6040518082815260200191505060405180910390f35b3480156104aa57600080fd5b506104b36112c8565b60405180821515815260200191505060405180910390f35b3480156104d757600080fd5b50610507600480360360208110156104ee57600080fd5b810190808035600f0b90602001909291905050506112db565b6040518082815260200191505060405180910390f35b34801561052957600080fd5b50610532611303565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561056a57600080fd5b5061057361132d565b005b34801561058157600080fd5b506105ae6004803603602081101561059857600080fd5b810190808035906020019092919050505061149a565b6040518082815260200191505060405180910390f35b3480156105d057600080fd5b506105d96115d2565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b506106046115d8565b6040518082815260200191505060405180910390f35b34801561062657600080fd5b5061062f61161d565b005b34801561063d57600080fd5b506106466116e9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561067e57600080fd5b50610687611712565b6040518082815260200191505060405180910390f35b3480156106a957600080fd5b506106e0600480360360408110156106c057600080fd5b81019080803590602001909291908035906020019092919050505061171c565b6040518082815260200191505060405180910390f35b34801561070257600080fd5b5061070b6118ef565b6040518082815260200191505060405180910390f35b34801561072d57600080fd5b5061075a6004803603602081101561074457600080fd5b81019080803590602001909291905050506118f9565b6040518082815260200191505060405180910390f35b6107b06004803603606081101561078657600080fd5b8101908080359060200190929190803590602001909291908035906020019092919050505061199d565b005b3480156107be57600080fd5b50610801600480360360208110156107d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e72565b005b34801561080f57600080fd5b50610818612064565b60405180821515815260200191505060405180910390f35b60008082141561084357600090506109fa565b60008290506000600190507201000000000000000000000000000000000000821061087757609082901c9150603081901b90505b6901000000000000000000821061089757604882901c9150601881901b90505b64100000000082106108b257602482901c9150600c81901b90505b6204000082106108cb57601282901c9150600681901b90505b61100082106108e357600c82901c9150600481901b90505b61020082106108fb57600982901c9150600381901b90505b6040821061091257600682901c9150600281901b90505b6008821061092257600181901b90505b6003816002026002830a868161093457fe5b04018161093d57fe5b0490506003816002026002830a868161095257fe5b04018161095b57fe5b0490506003816002026002830a868161097057fe5b04018161097957fe5b0490506003816002026002830a868161098e57fe5b04018161099757fe5b0490506003816002026002830a86816109ac57fe5b0401816109b557fe5b0490506003816002026002830a86816109ca57fe5b0401816109d357fe5b0490506003816002026002830a86816109e857fe5b0401816109f157fe5b04905080925050505b919050565b600080821415610a125760009050610aca565b610a1a61120a565b60035403821115610a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180612ccb6038913960400191505060405180910390fd5b6000610a8d8360035461210190919063ffffffff16565b90506000610a9d6003548361171c565b9050610ac5610ab660648361218490919063ffffffff16565b8261210190919063ffffffff16565b925050505b919050565b600760009054906101000a900460ff16610b51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f5468652074726164696e672069732064697361626c656400000000000000000081525060200191505060405180910390fd5b60003411610baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180612d95602a913960400191505060405180910390fd5b610bc160035460065461210190919063ffffffff16565b821115610c19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180612e166036913960400191505060405180910390fd5b6000610c243461149a565b905080831115610cdc57610c5582610c476127108661218490919063ffffffff16565b61207b90919063ffffffff16565b610c68828561210190919063ffffffff16565b10610cdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f536c6970706167652067726561746572207468616e20616c6c6f77656400000081525060200191505060405180910390fd5b5b60008184039050610cf88260035461220d90919063ffffffff16565b600381905550610d096003546118f9565b600481905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610da257600080fd5b505af1158015610db6573d6000803e3d6000fd5b505050506040513d6020811015610dcc57600080fd5b8101908080519060200190929190505050503373ffffffffffffffffffffffffffffffffffffffff167fa70108fc37a77e4fb183df412c5ec85d9c12294d6f4c1634c5d2a594a44db9aa8334600454600354866040518086815260200185815260200184815260200183815260200180602001838152602001828103825260038152602001807f6275790000000000000000000000000000000000000000000000000000000000815250602001965050505050505060405180910390a250505050565b60065481565b600080821415610ea85760009050610f38565b670de0b6b3a7640000821115610f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180612c686033913960400191505060405180910390fd5b610f35610f30610f20610f1b85611018565b612295565b610f2b600654611018565b6122be565b6112db565b90505b919050565b600080821415610f505760009050611013565b610f6760035460065461210190919063ffffffff16565b821115610fbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180612ccb6038913960400191505060405180910390fd5b6000610fd68360035461220d90919063ffffffff16565b90506000610fe68260035461171c565b905061100e610fff60648361218490919063ffffffff16565b8261210190919063ffffffff16565b925050505b919050565b600061103982600560009054906101000a900460ff1660ff16600a0a612329565b9050919050565b600560009054906101000a900460ff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b6000611089612391565b73ffffffffffffffffffffffffffffffffffffffff166110a76116e9565b73ffffffffffffffffffffffffffffffffffffffff1614611130576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600354141561118b573373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015611181573d6000803e3d6000fd5b5060019050611207565b60006111a060035461119b61120a565b61171c565b905060006111b7824761210190919063ffffffff16565b90503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156111ff573d6000803e3d6000fd5b506001925050505b90565b60006112c3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561127757600080fd5b505afa15801561128b573d6000803e3d6000fd5b505050506040513d60208110156112a157600080fd5b810190808051906020019092919050505060065461210190919063ffffffff16565b905090565b600760009054906101000a900460ff1681565b60006112fc82600560009054906101000a900460ff1660ff16600a0a612399565b9050919050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611335612391565b73ffffffffffffffffffffffffffffffffffffffff166113536116e9565b73ffffffffffffffffffffffffffffffffffffffff16146113dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000808214156114ad57600090506115cd565b60006114d56114c660648561218490919063ffffffff16565b8461210190919063ffffffff16565b905060006115666115616114f660065460065461207b90919063ffffffff16565b61155c6115576115176115096003612454565b61151289611018565b6122be565b61155261154261153b61152b600354611018565b611536600654611018565b612477565b60026124fa565b61154d600354611018565b6122be565b61280f565b6112db565b61207b565b610830565b90506006548111156115c3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612c426026913960400191505060405180910390fd5b6003548103925050505b919050565b60045481565b60008060035414156115ec5747905061161a565b60006116016003546115fc61120a565b61171c565b9050611616814761210190919063ffffffff16565b9150505b90565b611625612391565b73ffffffffffffffffffffffffffffffffffffffff166116436116e9565b73ffffffffffffffffffffffffffffffffffffffff16146116cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001600760006101000a81548160ff021916908315150217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600454905090565b600080828403141561173157600090506118e9565b818311611789576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612d246022913960400191505060405180910390fd5b6006548311156117e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612d67602e913960400191505060405180910390fd5b6117fb60035460065461210190919063ffffffff16565b61180e838561210190919063ffffffff16565b1115611865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612de8602e913960400191505060405180910390fd5b6118e66118e1611888611879600654611018565b6118836003612454565b612477565b6118dc6118b16118aa61189a89611018565b6118a5600654611018565b612477565b60036124fa565b6118d76118d06118c089611018565b6118cb600654611018565b612477565b60036124fa565b612876565b6122be565b6112db565b90505b92915050565b6000600354905090565b60008082141561190c5760009050611998565b600654821115611967576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180612c9b6030913960400191505060405180910390fd5b61199561199061198961197985611018565b611984600654611018565b612477565b60026124fa565b6112db565b90505b919050565b600083116119f6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612d466021913960400191505060405180910390fd5b6119fe61120a565b60035403831115611a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180612ccb6038913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015611b0357600080fd5b505af1158015611b17573d6000803e3d6000fd5b505050506040513d6020811015611b2d57600080fd5b8101908080519060200190929190505050831115611b96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180612dbf6029913960400191505060405180910390fd5b6000611ba1846109ff565b905080831115611c5957611bd282611bc46127108661218490919063ffffffff16565b61207b90919063ffffffff16565b611be5828561210190919063ffffffff16565b10611c58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f536c6970706167652067726561746572207468616e20616c6c6f77656400000081525060200191505060405180910390fd5b5b60008184039050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611d1157600080fd5b505af1158015611d25573d6000803e3d6000fd5b505050506040513d6020811015611d3b57600080fd5b810190808051906020019092919050505050611d628560035461210190919063ffffffff16565b600381905550611d736003546118f9565b6004819055503373ffffffffffffffffffffffffffffffffffffffff167fa70108fc37a77e4fb183df412c5ec85d9c12294d6f4c1634c5d2a594a44db9aa8684600454600354866040518086815260200185815260200184815260200183815260200180602001838152602001828103825260048152602001807f73656c6c00000000000000000000000000000000000000000000000000000000815250602001965050505050505060405180910390a23373ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015611e6a573d6000803e3d6000fd5b505050505050565b611e7a612391565b73ffffffffffffffffffffffffffffffffffffffff16611e986116e9565b73ffffffffffffffffffffffffffffffffffffffff1614611f21576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611fa7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612c1c6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600760009054906101000a900460ff16905090565b60008083141561208e57600090506120fb565b600082840290508284828161209f57fe5b04146120f6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612d036021913960400191505060405180910390fd5b809150505b92915050565b600082821115612179576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b60008082116121fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b81838161220457fe5b04905092915050565b60008082840190508381101561228b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008082600f0b12156122a757600080fd5b6122b7604083600f0b901b6128dd565b9050919050565b600080604083600f0b85600f0b02901d90507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b811215801561231657506f7fffffffffffffffffffffffffffffff600f0b8113155b61231f57600080fd5b8091505092915050565b60008082141561233857600080fd5b60006123448484612a5a565b90506f7fffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16111561238757600080fd5b8091505092915050565b600033905090565b6000808214156123ac576000905061244e565b600083600f0b12156123bd57600080fd5b600060406fffffffffffffffffffffffffffffffff841685600f0b02901c90506000608084901c85600f0b02905077ffffffffffffffffffffffffffffffffffffffffffffffff81111561241057600080fd5b604081901b9050817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0381111561244657600080fd5b818101925050505b92915050565b6000677fffffffffffffff82111561246b57600080fd5b604082901b9050919050565b60008082600f0b141561248957600080fd5b600082600f0b604085600f0b901b8161249e57fe5b0590507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b81121580156124e757506f7fffffffffffffffffffffffffffffff600f0b8113155b6124f057600080fd5b8091505092915050565b600080600084600f0b12801561251257506001808416145b905060008085600f0b12612526578461252b565b846000035b6fffffffffffffffffffffffffffffffff1690506000700100000000000000000000000000000000905068010000000000000000821161260557603f82901b91505b600085146125f9576000600186161461258a57607f828202901c90505b607f828302901c9150600060028616146125a857607f828202901c90505b607f828302901c9150600060048616146125c657607f828202901c90505b607f828302901c9150600060088616146125e457607f828202901c90505b607f828302901c9150600485901c945061256d565b604081901c905061279f565b6000603f90506c0100000000000000000000000083101561262e57602083901b92506020810390505b6e01000000000000000000000000000083101561265357601083901b92506010810390505b6f0100000000000000000000000000000083101561267957600883901b92506008810390505b6f1000000000000000000000000000000083101561269f57600483901b92506004810390505b6f400000000000000000000000000000008310156126c557600283901b92506002810390505b6f800000000000000000000000000000008310156126eb57600183901b92506001810390505b60005b60008714612786576040821061270357600080fd5b6000600188161461274457607f848402901c9250818101905070010000000000000000000000000000000083111561274357600183901c92506001810190505b5b607f848502901c9350600182901b9150700100000000000000000000000000000000841061277a57600184901c93506001820191505b600187901c96506126ee565b6040811061279357600080fd5b8060400383901c925050505b6000836127ac57816127b1565b816000035b90507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b81121580156127f957506f7fffffffffffffffffffffffffffffff600f0b8113155b61280257600080fd5b8094505050505092915050565b60008082600f0b84600f0b0190507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b811215801561286357506f7fffffffffffffffffffffffffffffff600f0b8113155b61286c57600080fd5b8091505092915050565b60008082600f0b84600f0b0390507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b81121580156128ca57506f7fffffffffffffffffffffffffffffff600f0b8113155b6128d357600080fd5b8091505092915050565b6000808214156128f05760009050612a55565b6000829050600060019050700100000000000000000000000000000000821061292257608082901c9150604081901b90505b68010000000000000000821061294157604082901c9150602081901b90505b640100000000821061295c57602082901c9150601081901b90505b62010000821061297557601082901c9150600881901b90505b610100821061298d57600882901c9150600481901b90505b601082106129a457600482901c9150600281901b90505b600882106129b457600181901b90505b60018185816129bf57fe5b048201901c905060018185816129d157fe5b048201901c905060018185816129e357fe5b048201901c905060018185816129f557fe5b048201901c90506001818581612a0757fe5b048201901c90506001818581612a1957fe5b048201901c90506001818581612a2b57fe5b048201901c90506000818581612a3d57fe5b049050808210612a4d5780612a4f565b815b93505050505b919050565b600080821415612a6957600080fd5b600077ffffffffffffffffffffffffffffffffffffffffffffffff8411612a9f5782604085901b81612a9757fe5b049050612bf4565b600060c09050600060c086901c90506401000000008110612ac857602081901c90506020820191505b620100008110612ae057601081901c90506010820191505b6101008110612af757600881901c90506008820191505b60108110612b0d57600481901c90506004820191505b60048110612b2357600281901c90506002820191505b60028110612b32576001820191505b600160bf830360018703901c018260ff0387901b81612b4d57fe5b0492506fffffffffffffffffffffffffffffffff831115612b6d57600080fd5b6000608086901c8402905060006fffffffffffffffffffffffffffffffff871685029050600060c089901c9050600060408a901b905082811015612bb2576001820391505b8281039050608084901b925082811015612bcd576001820391505b8281039050608084901c8214612bdf57fe5b888181612be857fe5b04870196505050505050505b6fffffffffffffffffffffffffffffffff811115612c1157600080fd5b809150509291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373537570706c7920546f702067726561746572207468616e20696e697469616c20737570706c79426f6e64696e67204375727665207465726d696e617465732062656c6f77204554482f624e4f4d20707269636520696e707574426f6e64696e67204375727665207465726d696e617465732062656c6f7720624e4f4d20616d6f756e7420696e70757453656c6c20616d6f756e74206f6620624e4f4d2067726561746572207468616e20756e626f6e64656420616d6f756e74206f6620624e4f4d536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77537570706c7920426f742067726561746572207468616e20537570706c7920546f7053656c6c20616d6f756e74206f6620624e4f4d20657175616c20746f207a65726f537570706c7920546f702067726561746572207468616e20696e697469616c20737570706c79206f6620624e4f4d416d6f756e74204554482073656e742077697468207265717565737420657175616c20746f207a65726f496e73756666696369656e7420426f6e6420436f6e747261637420624e4f4d20616c6c6f77616e6365526571756573742067726561746572207468616e2074686520626f6e64656420737570706c79206f6620624e4f4d457374696d6174656420616d6f756e74206f6620624e4f4d206772656174657220626f6e64656420737570706c79206f6620624e4f4da2646970667358221220866db4554f310636ac5cfb85df93ff7db7593ccde78f51b1154f09eaeb2a351664736f6c63430007060033536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f770000000000000000000000004fdf157c6860f33232608198419c74ed446ca577
Deployed Bytecode
0x6080604052600436106101b65760003560e01c806359eaced0116100ec5780638e117f6d1161008a578063daff394a11610064578063daff394a14610721578063eb208d6f14610770578063f2fde38b146107b2578063fa83cb5814610803576101b6565b80638e117f6d14610672578063afea58521461069d578063bc0f023c146106f6576101b6565b80637eda9347116100c65780637eda9347146105c457806389e85217146105ef5780638a8c523c1461061a5780638da5cb5b14610631576101b6565b806359eaced01461051d578063715018a61461055e5780637abe744814610575576101b6565b8063313ce567116101595780633ccfd60b116101335780633ccfd60b146104465780634477392b146104735780634ada218b1461049e5780635700f200146104cb576101b6565b8063313ce567146103ac5780633542a097146103da5780633c4df4fc1461041b576101b6565b80630dbe671f116101955780630dbe671f1461029157806325572aa4146102bc578063289044751461030b57806329b57f881461035a576101b6565b80627f39c7146101bb57806302689ad61461020a578063080d1f8214610259575b600080fd5b3480156101c757600080fd5b506101f4600480360360208110156101de57600080fd5b8101908080359060200190929190505050610830565b6040518082815260200191505060405180910390f35b34801561021657600080fd5b506102436004803603602081101561022d57600080fd5b81019080803590602001909291905050506109ff565b6040518082815260200191505060405180910390f35b61028f6004803603604081101561026f57600080fd5b810190808035906020019092919080359060200190929190505050610acf565b005b34801561029d57600080fd5b506102a6610e8f565b6040518082815260200191505060405180910390f35b3480156102c857600080fd5b506102f5600480360360208110156102df57600080fd5b8101908080359060200190929190505050610e95565b6040518082815260200191505060405180910390f35b34801561031757600080fd5b506103446004803603602081101561032e57600080fd5b8101908080359060200190929190505050610f3d565b6040518082815260200191505060405180910390f35b34801561036657600080fd5b506103936004803603602081101561037d57600080fd5b8101908080359060200190929190505050611018565b6040518082600f0b815260200191505060405180910390f35b3480156103b857600080fd5b506103c1611040565b604051808260ff16815260200191505060405180910390f35b3480156103e657600080fd5b506103ef611053565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561042757600080fd5b50610430611079565b6040518082815260200191505060405180910390f35b34801561045257600080fd5b5061045b61107f565b60405180821515815260200191505060405180910390f35b34801561047f57600080fd5b5061048861120a565b6040518082815260200191505060405180910390f35b3480156104aa57600080fd5b506104b36112c8565b60405180821515815260200191505060405180910390f35b3480156104d757600080fd5b50610507600480360360208110156104ee57600080fd5b810190808035600f0b90602001909291905050506112db565b6040518082815260200191505060405180910390f35b34801561052957600080fd5b50610532611303565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561056a57600080fd5b5061057361132d565b005b34801561058157600080fd5b506105ae6004803603602081101561059857600080fd5b810190808035906020019092919050505061149a565b6040518082815260200191505060405180910390f35b3480156105d057600080fd5b506105d96115d2565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b506106046115d8565b6040518082815260200191505060405180910390f35b34801561062657600080fd5b5061062f61161d565b005b34801561063d57600080fd5b506106466116e9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561067e57600080fd5b50610687611712565b6040518082815260200191505060405180910390f35b3480156106a957600080fd5b506106e0600480360360408110156106c057600080fd5b81019080803590602001909291908035906020019092919050505061171c565b6040518082815260200191505060405180910390f35b34801561070257600080fd5b5061070b6118ef565b6040518082815260200191505060405180910390f35b34801561072d57600080fd5b5061075a6004803603602081101561074457600080fd5b81019080803590602001909291905050506118f9565b6040518082815260200191505060405180910390f35b6107b06004803603606081101561078657600080fd5b8101908080359060200190929190803590602001909291908035906020019092919050505061199d565b005b3480156107be57600080fd5b50610801600480360360208110156107d557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e72565b005b34801561080f57600080fd5b50610818612064565b60405180821515815260200191505060405180910390f35b60008082141561084357600090506109fa565b60008290506000600190507201000000000000000000000000000000000000821061087757609082901c9150603081901b90505b6901000000000000000000821061089757604882901c9150601881901b90505b64100000000082106108b257602482901c9150600c81901b90505b6204000082106108cb57601282901c9150600681901b90505b61100082106108e357600c82901c9150600481901b90505b61020082106108fb57600982901c9150600381901b90505b6040821061091257600682901c9150600281901b90505b6008821061092257600181901b90505b6003816002026002830a868161093457fe5b04018161093d57fe5b0490506003816002026002830a868161095257fe5b04018161095b57fe5b0490506003816002026002830a868161097057fe5b04018161097957fe5b0490506003816002026002830a868161098e57fe5b04018161099757fe5b0490506003816002026002830a86816109ac57fe5b0401816109b557fe5b0490506003816002026002830a86816109ca57fe5b0401816109d357fe5b0490506003816002026002830a86816109e857fe5b0401816109f157fe5b04905080925050505b919050565b600080821415610a125760009050610aca565b610a1a61120a565b60035403821115610a76576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180612ccb6038913960400191505060405180910390fd5b6000610a8d8360035461210190919063ffffffff16565b90506000610a9d6003548361171c565b9050610ac5610ab660648361218490919063ffffffff16565b8261210190919063ffffffff16565b925050505b919050565b600760009054906101000a900460ff16610b51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f5468652074726164696e672069732064697361626c656400000000000000000081525060200191505060405180910390fd5b60003411610baa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180612d95602a913960400191505060405180910390fd5b610bc160035460065461210190919063ffffffff16565b821115610c19576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180612e166036913960400191505060405180910390fd5b6000610c243461149a565b905080831115610cdc57610c5582610c476127108661218490919063ffffffff16565b61207b90919063ffffffff16565b610c68828561210190919063ffffffff16565b10610cdb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f536c6970706167652067726561746572207468616e20616c6c6f77656400000081525060200191505060405180910390fd5b5b60008184039050610cf88260035461220d90919063ffffffff16565b600381905550610d096003546118f9565b600481905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015610da257600080fd5b505af1158015610db6573d6000803e3d6000fd5b505050506040513d6020811015610dcc57600080fd5b8101908080519060200190929190505050503373ffffffffffffffffffffffffffffffffffffffff167fa70108fc37a77e4fb183df412c5ec85d9c12294d6f4c1634c5d2a594a44db9aa8334600454600354866040518086815260200185815260200184815260200183815260200180602001838152602001828103825260038152602001807f6275790000000000000000000000000000000000000000000000000000000000815250602001965050505050505060405180910390a250505050565b60065481565b600080821415610ea85760009050610f38565b670de0b6b3a7640000821115610f09576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180612c686033913960400191505060405180910390fd5b610f35610f30610f20610f1b85611018565b612295565b610f2b600654611018565b6122be565b6112db565b90505b919050565b600080821415610f505760009050611013565b610f6760035460065461210190919063ffffffff16565b821115610fbf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180612ccb6038913960400191505060405180910390fd5b6000610fd68360035461220d90919063ffffffff16565b90506000610fe68260035461171c565b905061100e610fff60648361218490919063ffffffff16565b8261210190919063ffffffff16565b925050505b919050565b600061103982600560009054906101000a900460ff1660ff16600a0a612329565b9050919050565b600560009054906101000a900460ff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b6000611089612391565b73ffffffffffffffffffffffffffffffffffffffff166110a76116e9565b73ffffffffffffffffffffffffffffffffffffffff1614611130576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600354141561118b573373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015611181573d6000803e3d6000fd5b5060019050611207565b60006111a060035461119b61120a565b61171c565b905060006111b7824761210190919063ffffffff16565b90503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156111ff573d6000803e3d6000fd5b506001925050505b90565b60006112c3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561127757600080fd5b505afa15801561128b573d6000803e3d6000fd5b505050506040513d60208110156112a157600080fd5b810190808051906020019092919050505060065461210190919063ffffffff16565b905090565b600760009054906101000a900460ff1681565b60006112fc82600560009054906101000a900460ff1660ff16600a0a612399565b9050919050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611335612391565b73ffffffffffffffffffffffffffffffffffffffff166113536116e9565b73ffffffffffffffffffffffffffffffffffffffff16146113dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b6000808214156114ad57600090506115cd565b60006114d56114c660648561218490919063ffffffff16565b8461210190919063ffffffff16565b905060006115666115616114f660065460065461207b90919063ffffffff16565b61155c6115576115176115096003612454565b61151289611018565b6122be565b61155261154261153b61152b600354611018565b611536600654611018565b612477565b60026124fa565b61154d600354611018565b6122be565b61280f565b6112db565b61207b565b610830565b90506006548111156115c3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612c426026913960400191505060405180910390fd5b6003548103925050505b919050565b60045481565b60008060035414156115ec5747905061161a565b60006116016003546115fc61120a565b61171c565b9050611616814761210190919063ffffffff16565b9150505b90565b611625612391565b73ffffffffffffffffffffffffffffffffffffffff166116436116e9565b73ffffffffffffffffffffffffffffffffffffffff16146116cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6001600760006101000a81548160ff021916908315150217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600454905090565b600080828403141561173157600090506118e9565b818311611789576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180612d246022913960400191505060405180910390fd5b6006548311156117e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612d67602e913960400191505060405180910390fd5b6117fb60035460065461210190919063ffffffff16565b61180e838561210190919063ffffffff16565b1115611865576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e815260200180612de8602e913960400191505060405180910390fd5b6118e66118e1611888611879600654611018565b6118836003612454565b612477565b6118dc6118b16118aa61189a89611018565b6118a5600654611018565b612477565b60036124fa565b6118d76118d06118c089611018565b6118cb600654611018565b612477565b60036124fa565b612876565b6122be565b6112db565b90505b92915050565b6000600354905090565b60008082141561190c5760009050611998565b600654821115611967576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526030815260200180612c9b6030913960400191505060405180910390fd5b61199561199061198961197985611018565b611984600654611018565b612477565b60026124fa565b6112db565b90505b919050565b600083116119f6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612d466021913960400191505060405180910390fd5b6119fe61120a565b60035403831115611a5a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180612ccb6038913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015611b0357600080fd5b505af1158015611b17573d6000803e3d6000fd5b505050506040513d6020811015611b2d57600080fd5b8101908080519060200190929190505050831115611b96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180612dbf6029913960400191505060405180910390fd5b6000611ba1846109ff565b905080831115611c5957611bd282611bc46127108661218490919063ffffffff16565b61207b90919063ffffffff16565b611be5828561210190919063ffffffff16565b10611c58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f536c6970706167652067726561746572207468616e20616c6c6f77656400000081525060200191505060405180910390fd5b5b60008184039050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330886040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015611d1157600080fd5b505af1158015611d25573d6000803e3d6000fd5b505050506040513d6020811015611d3b57600080fd5b810190808051906020019092919050505050611d628560035461210190919063ffffffff16565b600381905550611d736003546118f9565b6004819055503373ffffffffffffffffffffffffffffffffffffffff167fa70108fc37a77e4fb183df412c5ec85d9c12294d6f4c1634c5d2a594a44db9aa8684600454600354866040518086815260200185815260200184815260200183815260200180602001838152602001828103825260048152602001807f73656c6c00000000000000000000000000000000000000000000000000000000815250602001965050505050505060405180910390a23373ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015611e6a573d6000803e3d6000fd5b505050505050565b611e7a612391565b73ffffffffffffffffffffffffffffffffffffffff16611e986116e9565b73ffffffffffffffffffffffffffffffffffffffff1614611f21576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611fa7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180612c1c6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600760009054906101000a900460ff16905090565b60008083141561208e57600090506120fb565b600082840290508284828161209f57fe5b04146120f6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612d036021913960400191505060405180910390fd5b809150505b92915050565b600082821115612179576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b818303905092915050565b60008082116121fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b81838161220457fe5b04905092915050565b60008082840190508381101561228b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008082600f0b12156122a757600080fd5b6122b7604083600f0b901b6128dd565b9050919050565b600080604083600f0b85600f0b02901d90507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b811215801561231657506f7fffffffffffffffffffffffffffffff600f0b8113155b61231f57600080fd5b8091505092915050565b60008082141561233857600080fd5b60006123448484612a5a565b90506f7fffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff16816fffffffffffffffffffffffffffffffff16111561238757600080fd5b8091505092915050565b600033905090565b6000808214156123ac576000905061244e565b600083600f0b12156123bd57600080fd5b600060406fffffffffffffffffffffffffffffffff841685600f0b02901c90506000608084901c85600f0b02905077ffffffffffffffffffffffffffffffffffffffffffffffff81111561241057600080fd5b604081901b9050817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0381111561244657600080fd5b818101925050505b92915050565b6000677fffffffffffffff82111561246b57600080fd5b604082901b9050919050565b60008082600f0b141561248957600080fd5b600082600f0b604085600f0b901b8161249e57fe5b0590507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b81121580156124e757506f7fffffffffffffffffffffffffffffff600f0b8113155b6124f057600080fd5b8091505092915050565b600080600084600f0b12801561251257506001808416145b905060008085600f0b12612526578461252b565b846000035b6fffffffffffffffffffffffffffffffff1690506000700100000000000000000000000000000000905068010000000000000000821161260557603f82901b91505b600085146125f9576000600186161461258a57607f828202901c90505b607f828302901c9150600060028616146125a857607f828202901c90505b607f828302901c9150600060048616146125c657607f828202901c90505b607f828302901c9150600060088616146125e457607f828202901c90505b607f828302901c9150600485901c945061256d565b604081901c905061279f565b6000603f90506c0100000000000000000000000083101561262e57602083901b92506020810390505b6e01000000000000000000000000000083101561265357601083901b92506010810390505b6f0100000000000000000000000000000083101561267957600883901b92506008810390505b6f1000000000000000000000000000000083101561269f57600483901b92506004810390505b6f400000000000000000000000000000008310156126c557600283901b92506002810390505b6f800000000000000000000000000000008310156126eb57600183901b92506001810390505b60005b60008714612786576040821061270357600080fd5b6000600188161461274457607f848402901c9250818101905070010000000000000000000000000000000083111561274357600183901c92506001810190505b5b607f848502901c9350600182901b9150700100000000000000000000000000000000841061277a57600184901c93506001820191505b600187901c96506126ee565b6040811061279357600080fd5b8060400383901c925050505b6000836127ac57816127b1565b816000035b90507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b81121580156127f957506f7fffffffffffffffffffffffffffffff600f0b8113155b61280257600080fd5b8094505050505092915050565b60008082600f0b84600f0b0190507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b811215801561286357506f7fffffffffffffffffffffffffffffff600f0b8113155b61286c57600080fd5b8091505092915050565b60008082600f0b84600f0b0390507fffffffffffffffffffffffffffffffff80000000000000000000000000000000600f0b81121580156128ca57506f7fffffffffffffffffffffffffffffff600f0b8113155b6128d357600080fd5b8091505092915050565b6000808214156128f05760009050612a55565b6000829050600060019050700100000000000000000000000000000000821061292257608082901c9150604081901b90505b68010000000000000000821061294157604082901c9150602081901b90505b640100000000821061295c57602082901c9150601081901b90505b62010000821061297557601082901c9150600881901b90505b610100821061298d57600882901c9150600481901b90505b601082106129a457600482901c9150600281901b90505b600882106129b457600181901b90505b60018185816129bf57fe5b048201901c905060018185816129d157fe5b048201901c905060018185816129e357fe5b048201901c905060018185816129f557fe5b048201901c90506001818581612a0757fe5b048201901c90506001818581612a1957fe5b048201901c90506001818581612a2b57fe5b048201901c90506000818581612a3d57fe5b049050808210612a4d5780612a4f565b815b93505050505b919050565b600080821415612a6957600080fd5b600077ffffffffffffffffffffffffffffffffffffffffffffffff8411612a9f5782604085901b81612a9757fe5b049050612bf4565b600060c09050600060c086901c90506401000000008110612ac857602081901c90506020820191505b620100008110612ae057601081901c90506010820191505b6101008110612af757600881901c90506008820191505b60108110612b0d57600481901c90506004820191505b60048110612b2357600281901c90506002820191505b60028110612b32576001820191505b600160bf830360018703901c018260ff0387901b81612b4d57fe5b0492506fffffffffffffffffffffffffffffffff831115612b6d57600080fd5b6000608086901c8402905060006fffffffffffffffffffffffffffffffff871685029050600060c089901c9050600060408a901b905082811015612bb2576001820391505b8281039050608084901b925082811015612bcd576001820391505b8281039050608084901c8214612bdf57fe5b888181612be857fe5b04870196505050505050505b6fffffffffffffffffffffffffffffffff811115612c1157600080fd5b809150509291505056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373537570706c7920546f702067726561746572207468616e20696e697469616c20737570706c79426f6e64696e67204375727665207465726d696e617465732062656c6f77204554482f624e4f4d20707269636520696e707574426f6e64696e67204375727665207465726d696e617465732062656c6f7720624e4f4d20616d6f756e7420696e70757453656c6c20616d6f756e74206f6620624e4f4d2067726561746572207468616e20756e626f6e64656420616d6f756e74206f6620624e4f4d536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77537570706c7920426f742067726561746572207468616e20537570706c7920546f7053656c6c20616d6f756e74206f6620624e4f4d20657175616c20746f207a65726f537570706c7920546f702067726561746572207468616e20696e697469616c20737570706c79206f6620624e4f4d416d6f756e74204554482073656e742077697468207265717565737420657175616c20746f207a65726f496e73756666696369656e7420426f6e6420436f6e747261637420624e4f4d20616c6c6f77616e6365526571756573742067726561746572207468616e2074686520626f6e64656420737570706c79206f6620624e4f4d457374696d6174656420616d6f756e74206f6620624e4f4d206772656174657220626f6e64656420737570706c79206f6620624e4f4da2646970667358221220866db4554f310636ac5cfb85df93ff7db7593ccde78f51b1154f09eaeb2a351664736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004fdf157c6860f33232608198419c74ed446ca577
-----Decoded View---------------
Arg [0] : NOMContAddr (address): 0x4fdF157C6860F33232608198419c74ED446Ca577
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000004fdf157c6860f33232608198419c74ed446ca577
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $3,607.01 | 13.8656 | $50,013.22 |
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.