Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 1,363 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mint | 18428337 | 537 days ago | IN | 0.45 ETH | 0.00139535 | ||||
Pause | 18428260 | 537 days ago | IN | 0 ETH | 0.00404057 | ||||
Withdraw | 18428247 | 537 days ago | IN | 0 ETH | 0.00224334 | ||||
Refund | 18428242 | 537 days ago | IN | 0 ETH | 0.33220051 | ||||
Mint | 18428242 | 537 days ago | IN | 0.61603812 ETH | 0.00286125 | ||||
Mint | 18428237 | 537 days ago | IN | 0.36020696 ETH | 0.00309359 | ||||
Mint | 18428237 | 537 days ago | IN | 0.4627126 ETH | 0.00309099 | ||||
Mint | 18428229 | 537 days ago | IN | 0.37 ETH | 0.0033839 | ||||
Mint | 18428227 | 537 days ago | IN | 0.35699969 ETH | 0.00341932 | ||||
Mint | 18428219 | 537 days ago | IN | 0.36020696 ETH | 0.0039045 | ||||
Mint | 18428206 | 537 days ago | IN | 0.35 ETH | 0.00455171 | ||||
Mint | 18428205 | 537 days ago | IN | 0.34445367 ETH | 0.02137937 | ||||
Mint | 18428203 | 537 days ago | IN | 0.34754822 ETH | 0.00511929 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34754822 ETH | 0.00460367 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34445367 ETH | 0.00460367 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34445367 ETH | 0.00460367 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34445367 ETH | 0.00460367 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34445367 ETH | 0.00461407 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34445367 ETH | 0.00460367 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34445367 ETH | 0.00461407 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34445367 ETH | 0.00461407 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34754822 ETH | 0.00473363 | ||||
Mint | 18428202 | 537 days ago | IN | 0.3667082 ETH | 0.00506663 | ||||
Mint | 18428202 | 537 days ago | IN | 0.34445367 ETH | 0.00485856 | ||||
Mint | 18428201 | 537 days ago | IN | 0.34754822 ETH | 0.00473868 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
Transfer | 18428247 | 537 days ago | 288.47173566 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01561302 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00861333 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00861333 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00861333 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00861333 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00861333 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00616155 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00616155 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00616155 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00616155 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01243431 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.01861333 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.00861333 ETH | ||||
Transfer | 18428242 | 537 days ago | 0.05861333 ETH |
Loading...
Loading
Contract Name:
DutchAuctionMinter
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "./lib/ABDKMathQuad.sol"; import "./interfaces/IMinter.sol"; contract DutchAuctionMinter is Pausable, AccessControl, ReentrancyGuard { /// minterType for this minter string public constant minterType = "DutchAuctionMinter"; bytes16 public HalfPeriod; bytes16 public BaseValue; // @notice Amount of time in seconds after each price drops uint256 public priceDropSlot; // @notice Role for pausing the contract bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); // @notice Role for set white list bytes32 public constant WHITELIST_ROLE = keccak256("WHITELIST_ROLE"); /// @notice ERC-721 pass contract whose tokens are minted by this auction /// @dev Must implement mint(address) IMinter public passes; /// @notice Timestamp when this auction starts allowing minting uint256 public startTime; /// @notice Starting price for the Dutch auction uint256 public startPrice; /// @notice Resting price where price descent ends uint256 public restPrice; /// @notice time of half period uint256 public halfPeriod; /// @notice total amount of minted passes uint256 public totalSupply; /// @notice total amount of free minted passes uint256 public totalFreeMint; /// @notice maximum amount of passes which can be minted uint256 public maxMint; uint256 private pauseStart; uint256 private pastPauseDelay; address public beneficiary; uint256 public projectId; bool public isRefund; /// @notice Timestamp when this free mint starts allowing minting uint256 public freeMintStartTime; uint256 public freeMintDuration; /// @notice the minest price of user bid for uint256 public minPrice; struct mintInfo { uint256 amount; uint256 totalPay; } mapping(address => mintInfo) private _mintInfos; address[] private _mintAddresses; mapping(address => uint256) public whitelist; /// @notice An event to be emitted upon pass purchases for the benefit of the UI event Purchase(address purchaser, uint256 tokenId, uint256 price); /// @notice An event emitted when mint being open for everyone or not. /// @dev open - true if mint open for everyone, false if not event MintPublicUpdated(bool open); /// @notice An event emitted when mint passes contract changed /// @dev newMintPasses - address of new mint passes contract event MintPassesUpdated(address newMintPasses); /// @notice An error returned when the auction has already started. error AlreadyStarted(); /// @notice An error returned when the auction has not yet started. error NotYetStarted(); /// @notice An error returned when funds transfer was not passed. error FailedPaying(address payee, bytes data); /// @notice An error returned when minting is not available for user. /// (mint not yet open for everyone and user don't have enough mint passes) error MintNotAvailable(); error Dissatisfied(); constructor( IMinter passes_, uint256 startTime_, uint256 startPrice_, uint256 restPrice_, uint256 priceDropSlot_, uint256 halfPeriod_, uint256 maxMint_, uint256 projectId_, address beneficiary_, uint256 freeMintStartTime_, uint256 freeMintDuration_ ) { // CHECKS inputs require(address(passes_) != address(0), "Pass contract must not be the zero address"); require(freeMintStartTime_ >= block.timestamp, "Start time for free mint cannot be in the past"); require(freeMintStartTime_ == startTime_ - freeMintDuration_, "auction must be later than free mint"); require(startPrice_ > 1e15, "Start price too low: check that prices are in wei"); require(restPrice_ > 1e15, "Rest price too low: check that prices are in wei"); require(startPrice_ >= restPrice_, "Start price must not be lower than rest price"); require(priceDropSlot_ > 0, "Price drop slot must be greater than 0"); require(halfPeriod_ > 0, "Half period must be greater than 0"); require(beneficiary_ != address(0), "Beneficiary must not be the zero address"); require(maxMint_ > 0, "Max mint must be greater than 0"); // EFFECTS passes = passes_; startTime = startTime_; startPrice = startPrice_; restPrice = restPrice_; priceDropSlot = priceDropSlot_; halfPeriod = halfPeriod_; maxMint = maxMint_; beneficiary = beneficiary_; projectId = projectId_; HalfPeriod = ABDKMathQuad.fromUInt(halfPeriod); BaseValue = ABDKMathQuad.fromUInt(startPrice); freeMintDuration = freeMintDuration_; freeMintStartTime = freeMintStartTime_; isRefund = false; _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(PAUSER_ROLE, msg.sender); _grantRole(WHITELIST_ROLE, msg.sender); } modifier started() { if (!isStarted()) revert NotYetStarted(); _; } modifier unstarted() { if (isStarted()) revert AlreadyStarted(); _; } // PUBLIC FUNCTIONS /// @notice Mint a pass on the `passes` contract. Must include at least `currentPrice`. function mint() external payable started whenNotPaused nonReentrant { // CHECKS inputs uint256 price = msg.value; uint256 cPrice = currentPrice(); require(price >= cPrice, "Insufficient payment"); require(totalSupply < maxMint, "Maximum mint reached"); if (_mintInfos[msg.sender].amount == 0 && price > restPrice) { _mintAddresses.push(msg.sender); } // EFFECTS unchecked { _mintInfos[msg.sender].amount++; _mintInfos[msg.sender].totalPay += price; minPrice = cPrice; totalSupply++; } uint256 id = passes.mint(msg.sender, projectId, msg.sender); emit Purchase(msg.sender, id, price); } /* /// @notice Mint up to three passes on the `passes` contract. Must include at least `currentPrice` * `quantity`. /// @param quantity The number of passes to mint: must be 1, 2, or 3 function mintMultiple(uint256 quantity) external payable started whenNotPaused nonReentrant { // CHECKS inputs require(quantity > 0, "Must mint at least one pass"); uint256 payment = msg.value; uint256 price = payment / quantity; uint256 cPrice = currentPrice(); require(price >= cPrice, "Insufficient payment"); require(totalSupply + quantity <= maxMint, "Maximum mint reached"); if (_mintInfos[msg.sender].amount == 0) { _mintAddresses.push(msg.sender); } // EFFECTS unchecked { // Unchecked arithmetic: totalSupply cannot exceed max mint totalSupply = totalSupply + quantity; _mintInfos[msg.sender].amount += quantity; _mintInfos[msg.sender].totalPay += price; minPrice = cPrice; } // EFFECTS + INTERACTIONS: call mint on known contract (passes.mint contains no external interactions) // One call without try/catch to make sure at least one is minted. for (uint256 i = 0; i < quantity; i++) { uint256 id = passes.mint(msg.sender, projectId, msg.sender); emit Purchase(msg.sender, id, price); } } */ // OWNER FUNCTIONS function setProjectId(uint256 projectId_) external unstarted onlyRole(DEFAULT_ADMIN_ROLE) { projectId = projectId_; } /// @notice Update the passes contract address /// @dev Can only be called by the contract `owner`. Reverts if the auction has already started. function setPasses(IMinter passes_) external unstarted onlyRole(DEFAULT_ADMIN_ROLE) { // CHECKS inputs require(address(passes_) != address(0), "Pass contract must not be the zero address"); // require(passes_.supportsInterface(0x6a627842), "Pass contract must support mint(address)"); // TODO // EFFECTS passes = passes_; } /// @notice Pause this contract /// @dev Can only be called by the contract `owner` function pause() public onlyRole(PAUSER_ROLE) { // CHECKS + EFFECTS: `Pausable` handles checking permissions and setting pause state super._pause(); // More EFFECTS pauseStart = block.timestamp; } /// @notice Resume this contract /// @dev Can only be called by the contract `owner`. Pricing tiers will pick up where they left off. function unpause() public onlyRole(PAUSER_ROLE) { // CHECKS + EFFECTS: `Pausable` handles checking permissions and setting pause state super._unpause(); // More EFFECTS if (block.timestamp <= startTime) { return; } // Find the amount time the auction should have been live, but was paused unchecked { // Unchecked arithmetic: computed value will be < block.timestamp and >= 0 if (pauseStart < startTime) { pastPauseDelay = block.timestamp - startTime; } else { pastPauseDelay += (block.timestamp - pauseStart); } } } function withdraw() public onlyRole(DEFAULT_ADMIN_ROLE) nonReentrant { uint256 balanceAvailable = address(this).balance; (bool success, bytes memory data) = beneficiary.call{value: balanceAvailable}(""); if (!success) revert FailedPaying(beneficiary, data); } function setStartTime(uint256 startTime_, uint256 freeStartTime_, uint256 freeMintDuration_) external unstarted onlyRole(DEFAULT_ADMIN_ROLE) { // CHECKS inputs require(freeStartTime_ >= block.timestamp, "New start time cannot be in the past"); require(freeStartTime_ == startTime_ - freeMintDuration_, "auction must be later than free mint"); // EFFECTS startTime = startTime_; freeMintDuration = freeMintDuration_; freeMintStartTime = freeStartTime_; } /// @notice Update the auction start time /// @dev Can only be called by the contract `owner`. Reverts if the auction has already started. function setMaxMint(uint256 maxMint_) external unstarted onlyRole(DEFAULT_ADMIN_ROLE) { // CHECKS inputs require(maxMint_ > 0, "Max mint must be greater than 0"); // EFFECTS maxMint = maxMint_; } /// @notice Update the auction price range and rate of decrease /// @dev Since the values are validated against each other, they are all set together. Can only be called by the /// contract `owner`. Reverts if the auction has already started. function setPriceRange(uint256 startPrice_, uint256 restPrice_, uint256 priceDropSlot_, uint256 halfPeriod_) external unstarted onlyRole(DEFAULT_ADMIN_ROLE) { // CHECKS inputs require(startPrice_ > 1e15, "Start price too low: check that prices are in wei"); require(restPrice_ > 1e15, "Rest price too low: check that prices are in wei"); require(startPrice_ >= restPrice_, "Start price must not be lower than rest price"); require(priceDropSlot_ > 0, "Price drop slot must be greater than 0"); require(halfPeriod_ > 0, "Half period must be greater than 0"); // EFFECTS startPrice = startPrice_; restPrice = restPrice_; priceDropSlot = priceDropSlot_; halfPeriod = halfPeriod_; HalfPeriod = ABDKMathQuad.fromUInt(halfPeriod); BaseValue = ABDKMathQuad.fromUInt(startPrice); } // VIEW FUNCTIONS /// @notice Query the current price function currentPrice() public view returns (uint256) { uint256 time = timeElapsed(); unchecked { time = (time / priceDropSlot) * priceDropSlot; } //function fromUInt (uint256 x) internal pure returns (bytes16) bytes16 currentTime = ABDKMathQuad.fromUInt(time); //first: currentTime / half period bytes16 step0 = ABDKMathQuad.div(currentTime, HalfPeriod); //second: pow_2 bytes16 step1 = ABDKMathQuad.pow_2(step0); //then: startPrice / step1 bytes16 step2 = ABDKMathQuad.div(BaseValue, step1); //last uint256 value = ABDKMathQuad.toUInt(step2); if (value < restPrice) { value = restPrice; } return value; } /// @notice Returns time of total decay period function decayTime() public view returns (uint256) { bytes16 step0 = ABDKMathQuad.log_2(BaseValue); bytes16 step1 = ABDKMathQuad.log_2(ABDKMathQuad.fromUInt(restPrice)); bytes16 result = ABDKMathQuad.mul(HalfPeriod, ABDKMathQuad.sub(step0, step1)); uint256 t = ABDKMathQuad.toUInt(result); unchecked { //padding 10 t = ((t + 10) / 10) * 10; } return t; } /// @notice Returns timestamp of next price drop function nextPriceDrop() public view returns (uint256) { if (!isStarted()) return startTime + priceDropSlot; uint256 timeUntilNextDrop = priceDropSlot - (timeElapsed() % priceDropSlot); return block.timestamp + timeUntilNextDrop; } function endTime() public view returns (uint256) { return startTime + decayTime() + pastPauseDelay; } function isStarted() internal view returns (bool) { return (paused() ? pauseStart : block.timestamp) >= startTime; } function timeElapsed() internal view returns (uint256) { if (!isStarted()) return 0; unchecked { // pastPauseDelay cannot be greater than the time passed since startTime. if (!paused()) { return block.timestamp - startTime - pastPauseDelay; } // pastPauseDelay cannot be greater than the time between startTime and pauseStart. return pauseStart - startTime - pastPauseDelay; } } /**free mint**/ function setWhiteList(address[] memory users, uint256[] memory amounts) external onlyRole(WHITELIST_ROLE) { assembly { let length := mload(users) let lengthAmount := mload(amounts) if eq(length, lengthAmount) { let usersPtr := add(users, 0x20) let amountsPtr := add(amounts, 0x20) let i := 0 for {} lt(i, length) {} { let user := mload(add(usersPtr, mul(i, 0x20))) let amount := mload(add(amountsPtr, mul(i, 0x20))) mstore(0, user) mstore(32, whitelist.slot) let hash := keccak256(0, 64) sstore(hash, amount) i := add(i, 1) } } } } function freeMint() external whenNotPaused nonReentrant { require(freeMintStartTime <= block.timestamp && freeMintStartTime + freeMintDuration > block.timestamp, "free mint not valid"); if (whitelist[msg.sender] == 0) { revert Dissatisfied(); } //处理free mint for (uint256 i = 0; i < whitelist[msg.sender]; i++) { uint256 id = passes.mint(msg.sender, projectId, msg.sender); emit Purchase(msg.sender, id, 0); } unchecked { totalFreeMint += whitelist[msg.sender]; totalSupply += whitelist[msg.sender]; } //set 0 whitelist[msg.sender] = 0; } function refund() external whenNotPaused onlyRole(DEFAULT_ADMIN_ROLE) { require(!isRefund, "has refunded"); isRefund = true; uint256 refunds; address user; for (uint256 i = 0; i < _mintAddresses.length; i++) { user = _mintAddresses[i]; refunds = _mintInfos[user].totalPay - _mintInfos[user].amount * minPrice; assembly { if gt(refunds, 0) { let callStatus := call( gas(), user, refunds, 0, 0, 0, 0 ) } } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: BSD-4-Clause /* * ABDK Math Quad Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.8.17; /** * Smart contract library of mathematical functions operating with IEEE 754 * quadruple-precision binary floating-point numbers (quadruple precision * numbers). As long as quadruple precision numbers are 16-bytes long, they are * represented by bytes16 type. */ library ABDKMathQuad { /* * 0. */ bytes16 private constant POSITIVE_ZERO = 0x00000000000000000000000000000000; /* * -0. */ bytes16 private constant NEGATIVE_ZERO = 0x80000000000000000000000000000000; /* * +Infinity. */ bytes16 private constant POSITIVE_INFINITY = 0x7FFF0000000000000000000000000000; /* * -Infinity. */ bytes16 private constant NEGATIVE_INFINITY = 0xFFFF0000000000000000000000000000; /* * Canonical NaN value. */ bytes16 private constant NaN = 0x7FFF8000000000000000000000000000; /** * Convert signed 256-bit integer number into quadruple precision number. * * @param x signed 256-bit integer number * @return quadruple precision number */ function fromInt(int256 x) internal pure returns (bytes16) { unchecked { if (x == 0) { return bytes16(0); } else { // We rely on overflow behavior here uint256 result = uint256(x > 0 ? x : -x); uint256 msb = mostSignificantBit(result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16(uint128(result)); } } } /** * Convert quadruple precision number into signed 256-bit integer number * rounding towards zero. Revert on overflow. * * @param x quadruple precision number * @return signed 256-bit integer number */ function toInt(bytes16 x) internal pure returns (int256) { unchecked { uint256 exponent = uint128(x) >> 112 & 0x7FFF; require(exponent <= 16638); // Overflow if (exponent < 16383) return 0; // Underflow uint256 result = uint256(uint128(x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; if (uint128(x) >= 0x80000000000000000000000000000000) { // Negative require(result <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256(result); // We rely on overflow behavior here } else { require(result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256(result); } } } /** * Convert unsigned 256-bit integer number into quadruple precision number. * * @param x unsigned 256-bit integer number * @return quadruple precision number */ function fromUInt(uint256 x) internal pure returns (bytes16) { unchecked { if (x == 0) { return bytes16(0); } else { uint256 result = x; uint256 msb = mostSignificantBit(result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; return bytes16(uint128(result)); } } } /** * Convert quadruple precision number into unsigned 256-bit integer number * rounding towards zero. Revert on underflow. Note, that negative floating * point numbers in range (-1.0 .. 0.0) may be converted to unsigned integer * without error, because they are rounded to zero. * * @param x quadruple precision number * @return unsigned 256-bit integer number */ function toUInt(bytes16 x) internal pure returns (uint256) { unchecked { uint256 exponent = uint128(x) >> 112 & 0x7FFF; if (exponent < 16383) return 0; // Underflow require(uint128(x) < 0x80000000000000000000000000000000); // Negative require(exponent <= 16638); // Overflow uint256 result = uint256(uint128(x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; return result; } } /** * Convert signed 128.128 bit fixed point number into quadruple precision * number. * * @param x signed 128.128 bit fixed point number * @return quadruple precision number */ function from128x128(int256 x) internal pure returns (bytes16) { unchecked { if (x == 0) { return bytes16(0); } else { // We rely on overflow behavior here uint256 result = uint256(x > 0 ? x : -x); uint256 msb = mostSignificantBit(result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16255 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16(uint128(result)); } } } /** * Convert quadruple precision number into signed 128.128 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 128.128 bit fixed point number */ function to128x128(bytes16 x) internal pure returns (int256) { unchecked { uint256 exponent = uint128(x) >> 112 & 0x7FFF; require(exponent <= 16510); // Overflow if (exponent < 16255) return 0; // Underflow uint256 result = uint256(uint128(x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16367) result >>= 16367 - exponent; else if (exponent > 16367) result <<= exponent - 16367; if (uint128(x) >= 0x80000000000000000000000000000000) { // Negative require(result <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256(result); // We rely on overflow behavior here } else { require(result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256(result); } } } /** * Convert signed 64.64 bit fixed point number into quadruple precision * number. * * @param x signed 64.64 bit fixed point number * @return quadruple precision number */ function from64x64(int128 x) internal pure returns (bytes16) { unchecked { if (x == 0) { return bytes16(0); } else { // We rely on overflow behavior here uint256 result = uint128(x > 0 ? x : -x); uint256 msb = mostSignificantBit(result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16319 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16(uint128(result)); } } } /** * Convert quadruple precision number into signed 64.64 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 64.64 bit fixed point number */ function to64x64(bytes16 x) internal pure returns (int128) { unchecked { uint256 exponent = uint128(x) >> 112 & 0x7FFF; require(exponent <= 16446); // Overflow if (exponent < 16319) return 0; // Underflow uint256 result = uint256(uint128(x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16431) result >>= 16431 - exponent; else if (exponent > 16431) result <<= exponent - 16431; if (uint128(x) >= 0x80000000000000000000000000000000) { // Negative require(result <= 0x80000000000000000000000000000000); return -int128(int256(result)); // We rely on overflow behavior here } else { require(result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128(int256(result)); } } } /** * Convert octuple precision number into quadruple precision number. * * @param x octuple precision number * @return quadruple precision number */ function fromOctuple(bytes32 x) internal pure returns (bytes16) { unchecked { bool negative = x & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0; uint256 exponent = uint256(x) >> 236 & 0x7FFFF; uint256 significand = uint256(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFFF) { if (significand > 0) return NaN; else return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; } if (exponent > 278526) { return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; } else if (exponent < 245649) { return negative ? NEGATIVE_ZERO : POSITIVE_ZERO; } else if (exponent < 245761) { significand = (significand | 0x100000000000000000000000000000000000000000000000000000000000) >> 245885 - exponent; exponent = 0; } else { significand >>= 124; exponent -= 245760; } uint128 result = uint128(significand | exponent << 112); if (negative) result |= 0x80000000000000000000000000000000; return bytes16(result); } } /** * Convert quadruple precision number into octuple precision number. * * @param x quadruple precision number * @return octuple precision number */ function toOctuple(bytes16 x) internal pure returns (bytes32) { unchecked { uint256 exponent = uint128(x) >> 112 & 0x7FFF; uint256 result = uint128(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) { exponent = 0x7FFFF; } // Infinity or NaN else if (exponent == 0) { if (result > 0) { uint256 msb = mostSignificantBit(result); result = result << 236 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 245649 + msb; } } else { result <<= 124; exponent += 245760; } result |= exponent << 236; if (uint128(x) >= 0x80000000000000000000000000000000) { result |= 0x8000000000000000000000000000000000000000000000000000000000000000; } return bytes32(result); } } /** * Convert double precision number into quadruple precision number. * * @param x double precision number * @return quadruple precision number */ function fromDouble(bytes8 x) internal pure returns (bytes16) { unchecked { uint256 exponent = uint64(x) >> 52 & 0x7FF; uint256 result = uint64(x) & 0xFFFFFFFFFFFFF; if (exponent == 0x7FF) { exponent = 0x7FFF; } // Infinity or NaN else if (exponent == 0) { if (result > 0) { uint256 msb = mostSignificantBit(result); result = result << 112 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 15309 + msb; } } else { result <<= 60; exponent += 15360; } result |= exponent << 112; if (x & 0x8000000000000000 > 0) { result |= 0x80000000000000000000000000000000; } return bytes16(uint128(result)); } } /** * Convert quadruple precision number into double precision number. * * @param x quadruple precision number * @return double precision number */ function toDouble(bytes16 x) internal pure returns (bytes8) { unchecked { bool negative = uint128(x) >= 0x80000000000000000000000000000000; uint256 exponent = uint128(x) >> 112 & 0x7FFF; uint256 significand = uint128(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) { if (significand > 0) { return 0x7FF8000000000000; } // NaN else { return negative ? bytes8(0xFFF0000000000000) // -Infinity : bytes8(0x7FF0000000000000); } // Infinity } if (exponent > 17406) { return negative ? bytes8(0xFFF0000000000000) // -Infinity : bytes8(0x7FF0000000000000); } // Infinity else if (exponent < 15309) { return negative ? bytes8(0x8000000000000000) // -0 : bytes8(0x0000000000000000); } // 0 else if (exponent < 15361) { significand = (significand | 0x10000000000000000000000000000) >> 15421 - exponent; exponent = 0; } else { significand >>= 60; exponent -= 15360; } uint64 result = uint64(significand | exponent << 52); if (negative) result |= 0x8000000000000000; return bytes8(result); } } /** * Test whether given quadruple precision number is NaN. * * @param x quadruple precision number * @return true if x is NaN, false otherwise */ function isNaN(bytes16 x) internal pure returns (bool) { unchecked { return uint128(x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF > 0x7FFF0000000000000000000000000000; } } /** * Test whether given quadruple precision number is positive or negative * infinity. * * @param x quadruple precision number * @return true if x is positive or negative infinity, false otherwise */ function isInfinity(bytes16 x) internal pure returns (bool) { unchecked { return uint128(x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x7FFF0000000000000000000000000000; } } /** * Calculate sign of x, i.e. -1 if x is negative, 0 if x if zero, and 1 if x * is positive. Note that sign (-0) is zero. Revert if x is NaN. * * @param x quadruple precision number * @return sign of x */ function sign(bytes16 x) internal pure returns (int8) { unchecked { uint128 absoluteX = uint128(x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require(absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN if (absoluteX == 0) return 0; else if (uint128(x) >= 0x80000000000000000000000000000000) return -1; else return 1; } } /** * Calculate sign (x - y). Revert if either argument is NaN, or both * arguments are infinities of the same sign. * * @param x quadruple precision number * @param y quadruple precision number * @return sign (x - y) */ function cmp(bytes16 x, bytes16 y) internal pure returns (int8) { unchecked { uint128 absoluteX = uint128(x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require(absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN uint128 absoluteY = uint128(y) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require(absoluteY <= 0x7FFF0000000000000000000000000000); // Not NaN // Not infinities of the same sign require(x != y || absoluteX < 0x7FFF0000000000000000000000000000); if (x == y) { return 0; } else { bool negativeX = uint128(x) >= 0x80000000000000000000000000000000; bool negativeY = uint128(y) >= 0x80000000000000000000000000000000; if (negativeX) { if (negativeY) return absoluteX > absoluteY ? -1 : int8(1); else return -1; } else { if (negativeY) return 1; else return absoluteX > absoluteY ? int8(1) : -1; } } } } /** * Test whether x equals y. NaN, infinity, and -infinity are not equal to * anything. * * @param x quadruple precision number * @param y quadruple precision number * @return true if x equals to y, false otherwise */ function eq(bytes16 x, bytes16 y) internal pure returns (bool) { unchecked { if (x == y) { return uint128(x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF < 0x7FFF0000000000000000000000000000; } else { return false; } } } /** * Calculate x + y. Special values behave in the following way: * * NaN + x = NaN for any x. * Infinity + x = Infinity for any finite x. * -Infinity + x = -Infinity for any finite x. * Infinity + Infinity = Infinity. * -Infinity + -Infinity = -Infinity. * Infinity + -Infinity = -Infinity + Infinity = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function add(bytes16 x, bytes16 y) internal pure returns (bytes16) { unchecked { uint256 xExponent = uint128(x) >> 112 & 0x7FFF; uint256 yExponent = uint128(y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x; else return NaN; } else { return x; } } else if (yExponent == 0x7FFF) { return y; } else { bool xSign = uint128(x) >= 0x80000000000000000000000000000000; uint256 xSignifier = uint128(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; bool ySign = uint128(y) >= 0x80000000000000000000000000000000; uint256 ySignifier = uint128(y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) { return y == NEGATIVE_ZERO ? POSITIVE_ZERO : y; } else if (ySignifier == 0) { return x == NEGATIVE_ZERO ? POSITIVE_ZERO : x; } else { int256 delta = int256(xExponent) - int256(yExponent); if (xSign == ySign) { if (delta > 112) { return x; } else if (delta > 0) { ySignifier >>= uint256(delta); } else if (delta < -112) { return y; } else if (delta < 0) { xSignifier >>= uint256(-delta); xExponent = yExponent; } xSignifier += ySignifier; if (xSignifier >= 0x20000000000000000000000000000) { xSignifier >>= 1; xExponent += 1; } if (xExponent == 0x7FFF) { return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; } else { if (xSignifier < 0x10000000000000000000000000000) xExponent = 0; else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; return bytes16( uint128( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier ) ); } } else { if (delta > 0) { xSignifier <<= 1; xExponent -= 1; } else if (delta < 0) { ySignifier <<= 1; xExponent = yExponent - 1; } if (delta > 112) ySignifier = 1; else if (delta > 1) ySignifier = (ySignifier - 1 >> uint256(delta - 1)) + 1; else if (delta < -112) xSignifier = 1; else if (delta < -1) xSignifier = (xSignifier - 1 >> uint256(-delta - 1)) + 1; if (xSignifier >= ySignifier) { xSignifier -= ySignifier; } else { xSignifier = ySignifier - xSignifier; xSign = ySign; } if (xSignifier == 0) { return POSITIVE_ZERO; } uint256 msb = mostSignificantBit(xSignifier); if (msb == 113) { xSignifier = xSignifier >> 1 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent += 1; } else if (msb < 112) { uint256 shift = 112 - msb; if (xExponent > shift) { xSignifier = xSignifier << shift & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent -= shift; } else { xSignifier <<= xExponent - 1; xExponent = 0; } } else { xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } if (xExponent == 0x7FFF) { return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; } else { return bytes16( uint128( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier ) ); } } } } } } /** * Calculate x - y. Special values behave in the following way: * * NaN - x = NaN for any x. * Infinity - x = Infinity for any finite x. * -Infinity - x = -Infinity for any finite x. * Infinity - -Infinity = Infinity. * -Infinity - Infinity = -Infinity. * Infinity - Infinity = -Infinity - -Infinity = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function sub(bytes16 x, bytes16 y) internal pure returns (bytes16) { unchecked { return add(x, y ^ 0x80000000000000000000000000000000); } } /** * Calculate x * y. Special values behave in the following way: * * NaN * x = NaN for any x. * Infinity * x = Infinity for any finite positive x. * Infinity * x = -Infinity for any finite negative x. * -Infinity * x = -Infinity for any finite positive x. * -Infinity * x = Infinity for any finite negative x. * Infinity * 0 = NaN. * -Infinity * 0 = NaN. * Infinity * Infinity = Infinity. * Infinity * -Infinity = -Infinity. * -Infinity * Infinity = -Infinity. * -Infinity * -Infinity = Infinity. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function mul(bytes16 x, bytes16 y) internal pure returns (bytes16) { unchecked { uint256 xExponent = uint128(x) >> 112 & 0x7FFF; uint256 yExponent = uint128(y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x ^ y & 0x80000000000000000000000000000000; else if (x ^ y == 0x80000000000000000000000000000000) return x | y; else return NaN; } else { if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return x ^ y & 0x80000000000000000000000000000000; } } else if (yExponent == 0x7FFF) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return y ^ x & 0x80000000000000000000000000000000; } else { uint256 xSignifier = uint128(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; uint256 ySignifier = uint128(y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; xSignifier *= ySignifier; if (xSignifier == 0) { return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; } xExponent += yExponent; uint256 msb = xSignifier >= 0x200000000000000000000000000000000000000000000000000000000 ? 225 : xSignifier >= 0x100000000000000000000000000000000000000000000000000000000 ? 224 : mostSignificantBit(xSignifier); if (xExponent + msb < 16496) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb < 16608) { // Subnormal if (xExponent < 16496) { xSignifier >>= 16496 - xExponent; } else if (xExponent > 16496) { xSignifier <<= xExponent - 16496; } xExponent = 0; } else if (xExponent + msb > 49373) { xExponent = 0x7FFF; xSignifier = 0; } else { if (msb > 112) { xSignifier >>= msb - 112; } else if (msb < 112) { xSignifier <<= 112 - msb; } xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb - 16607; } return bytes16( uint128(uint128((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier) ); } } } /** * Calculate x / y. Special values behave in the following way: * * NaN / x = NaN for any x. * x / NaN = NaN for any x. * Infinity / x = Infinity for any finite non-negative x. * Infinity / x = -Infinity for any finite negative x including -0. * -Infinity / x = -Infinity for any finite non-negative x. * -Infinity / x = Infinity for any finite negative x including -0. * x / Infinity = 0 for any finite non-negative x. * x / -Infinity = -0 for any finite non-negative x. * x / Infinity = -0 for any finite non-negative x including -0. * x / -Infinity = 0 for any finite non-negative x including -0. * * Infinity / Infinity = NaN. * Infinity / -Infinity = -NaN. * -Infinity / Infinity = -NaN. * -Infinity / -Infinity = NaN. * * Division by zero behaves in the following way: * * x / 0 = Infinity for any finite positive x. * x / -0 = -Infinity for any finite positive x. * x / 0 = -Infinity for any finite negative x. * x / -0 = Infinity for any finite negative x. * 0 / 0 = NaN. * 0 / -0 = NaN. * -0 / 0 = NaN. * -0 / -0 = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function div(bytes16 x, bytes16 y) internal pure returns (bytes16) { unchecked { uint256 xExponent = uint128(x) >> 112 & 0x7FFF; uint256 yExponent = uint128(y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) return NaN; else return x ^ y & 0x80000000000000000000000000000000; } else if (yExponent == 0x7FFF) { if (y & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF != 0) return NaN; else return POSITIVE_ZERO | (x ^ y) & 0x80000000000000000000000000000000; } else if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return POSITIVE_INFINITY | (x ^ y) & 0x80000000000000000000000000000000; } else { uint256 ySignifier = uint128(y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; uint256 xSignifier = uint128(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) { if (xSignifier != 0) { uint256 shift = 226 - mostSignificantBit(xSignifier); xSignifier <<= shift; xExponent = 1; yExponent += shift - 114; } } else { xSignifier = (xSignifier | 0x10000000000000000000000000000) << 114; } xSignifier = xSignifier / ySignifier; if (xSignifier == 0) { return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; } assert(xSignifier >= 0x1000000000000000000000000000); uint256 msb = xSignifier >= 0x80000000000000000000000000000 ? mostSignificantBit(xSignifier) : xSignifier >= 0x40000000000000000000000000000 ? 114 : xSignifier >= 0x20000000000000000000000000000 ? 113 : 112; if (xExponent + msb > yExponent + 16497) { // Overflow xExponent = 0x7FFF; xSignifier = 0; } else if (xExponent + msb + 16380 < yExponent) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb + 16268 < yExponent) { // Subnormal if (xExponent + 16380 > yExponent) { xSignifier <<= xExponent + 16380 - yExponent; } else if (xExponent + 16380 < yExponent) { xSignifier >>= yExponent - xExponent - 16380; } xExponent = 0; } else { // Normal if (msb > 112) { xSignifier >>= msb - 112; } xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb + 16269 - yExponent; } return bytes16( uint128(uint128((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier) ); } } } /** * Calculate -x. * * @param x quadruple precision number * @return quadruple precision number */ function neg(bytes16 x) internal pure returns (bytes16) { unchecked { return x ^ 0x80000000000000000000000000000000; } } /** * Calculate |x|. * * @param x quadruple precision number * @return quadruple precision number */ function abs(bytes16 x) internal pure returns (bytes16) { unchecked { return x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } } /** * Calculate square root of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function sqrt(bytes16 x) internal pure returns (bytes16) { unchecked { if (uint128(x) > 0x80000000000000000000000000000000) { return NaN; } else { uint256 xExponent = uint128(x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { return x; } else { uint256 xSignifier = uint128(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return POSITIVE_ZERO; bool oddExponent = xExponent & 0x1 == 0; xExponent = xExponent + 16383 >> 1; if (oddExponent) { if (xSignifier >= 0x10000000000000000000000000000) { xSignifier <<= 113; } else { uint256 msb = mostSignificantBit(xSignifier); uint256 shift = (226 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } else { if (xSignifier >= 0x10000000000000000000000000000) { xSignifier <<= 112; } else { uint256 msb = mostSignificantBit(xSignifier); uint256 shift = (225 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } uint256 r = 0x10000000000000000000000000000; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; // Seven iterations should be enough uint256 r1 = xSignifier / r; if (r1 < r) r = r1; return bytes16(uint128(xExponent << 112 | r & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } } /** * Calculate binary logarithm of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function log_2(bytes16 x) internal pure returns (bytes16) { unchecked { if (uint128(x) > 0x80000000000000000000000000000000) { return NaN; } else if (x == 0x3FFF0000000000000000000000000000) { return POSITIVE_ZERO; } else { uint256 xExponent = uint128(x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { return x; } else { uint256 xSignifier = uint128(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return NEGATIVE_INFINITY; bool resultNegative; uint256 resultExponent = 16495; uint256 resultSignifier; if (xExponent >= 0x3FFF) { resultNegative = false; resultSignifier = xExponent - 0x3FFF; xSignifier <<= 15; } else { resultNegative = true; if (xSignifier >= 0x10000000000000000000000000000) { resultSignifier = 0x3FFE - xExponent; xSignifier <<= 15; } else { uint256 msb = mostSignificantBit(xSignifier); resultSignifier = 16493 - msb; xSignifier <<= 127 - msb; } } if (xSignifier == 0x80000000000000000000000000000000) { if (resultNegative) resultSignifier += 1; uint256 shift = 112 - mostSignificantBit(resultSignifier); resultSignifier <<= shift; resultExponent -= shift; } else { uint256 bb = resultNegative ? 1 : 0; while (resultSignifier < 0x10000000000000000000000000000) { resultSignifier <<= 1; resultExponent -= 1; xSignifier *= xSignifier; uint256 b = xSignifier >> 255; resultSignifier += b ^ bb; xSignifier >>= 127 + b; } } return bytes16( uint128( (resultNegative ? 0x80000000000000000000000000000000 : 0) | resultExponent << 112 | resultSignifier & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) ); } } } } /** * Calculate natural logarithm of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function ln(bytes16 x) internal pure returns (bytes16) { unchecked { return mul(log_2(x), 0x3FFE62E42FEFA39EF35793C7673007E5); } } /** * Calculate 2^x. * * @param x quadruple precision number * @return quadruple precision number */ function pow_2(bytes16 x) internal pure returns (bytes16) { unchecked { bool xNegative = uint128(x) > 0x80000000000000000000000000000000; uint256 xExponent = uint128(x) >> 112 & 0x7FFF; uint256 xSignifier = uint128(x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF && xSignifier != 0) { return NaN; } else if (xExponent > 16397) { return xNegative ? POSITIVE_ZERO : POSITIVE_INFINITY; } else if (xExponent < 16255) { return 0x3FFF0000000000000000000000000000; } else { if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xExponent > 16367) { xSignifier <<= xExponent - 16367; } else if (xExponent < 16367) { xSignifier >>= 16367 - xExponent; } if (xNegative && xSignifier > 0x406E00000000000000000000000000000000) { return POSITIVE_ZERO; } if (!xNegative && xSignifier > 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) { return POSITIVE_INFINITY; } uint256 resultExponent = xSignifier >> 128; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xNegative && xSignifier != 0) { xSignifier = ~xSignifier; resultExponent += 1; } uint256 resultSignifier = 0x80000000000000000000000000000000; if (xSignifier & 0x80000000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; } if (xSignifier & 0x40000000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; } if (xSignifier & 0x20000000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; } if (xSignifier & 0x10000000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10B5586CF9890F6298B92B71842A98363 >> 128; } if (xSignifier & 0x8000000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; } if (xSignifier & 0x4000000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; } if (xSignifier & 0x2000000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; } if (xSignifier & 0x1000000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; } if (xSignifier & 0x800000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; } if (xSignifier & 0x400000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; } if (xSignifier & 0x200000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; } if (xSignifier & 0x100000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; } if (xSignifier & 0x80000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; } if (xSignifier & 0x40000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; } if (xSignifier & 0x20000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000162E525EE054754457D5995292026 >> 128; } if (xSignifier & 0x10000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000B17255775C040618BF4A4ADE83FC >> 128; } if (xSignifier & 0x8000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; } if (xSignifier & 0x4000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; } if (xSignifier & 0x2000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000162E43F4F831060E02D839A9D16D >> 128; } if (xSignifier & 0x1000000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000B1721BCFC99D9F890EA06911763 >> 128; } if (xSignifier & 0x800000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; } if (xSignifier & 0x400000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; } if (xSignifier & 0x200000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000162E430E5A18F6119E3C02282A5 >> 128; } if (xSignifier & 0x100000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; } if (xSignifier & 0x80000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; } if (xSignifier & 0x40000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000002C5C8601CC6B9E94213C72737A >> 128; } if (xSignifier & 0x20000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; } if (xSignifier & 0x10000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; } if (xSignifier & 0x8000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; } if (xSignifier & 0x4000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; } if (xSignifier & 0x2000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; } if (xSignifier & 0x1000000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000B17217F80F4EF5AADDA45554 >> 128; } if (xSignifier & 0x800000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; } if (xSignifier & 0x400000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; } if (xSignifier & 0x200000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000162E42FEFB2FED257559BDAA >> 128; } if (xSignifier & 0x100000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; } if (xSignifier & 0x80000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; } if (xSignifier & 0x40000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; } if (xSignifier & 0x20000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000162E42FEFA494F1478FDE05 >> 128; } if (xSignifier & 0x10000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000B17217F7D20CF927C8E94C >> 128; } if (xSignifier & 0x8000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; } if (xSignifier & 0x4000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000002C5C85FDF477B662B26945 >> 128; } if (xSignifier & 0x2000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000162E42FEFA3AE53369388C >> 128; } if (xSignifier & 0x1000000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000B17217F7D1D351A389D40 >> 128; } if (xSignifier & 0x800000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; } if (xSignifier & 0x400000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; } if (xSignifier & 0x200000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000162E42FEFA39FE95583C2 >> 128; } if (xSignifier & 0x100000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; } if (xSignifier & 0x80000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; } if (xSignifier & 0x40000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000002C5C85FDF473E242EA38 >> 128; } if (xSignifier & 0x20000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000162E42FEFA39F02B772C >> 128; } if (xSignifier & 0x10000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000B17217F7D1CF7D83C1A >> 128; } if (xSignifier & 0x8000000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; } if (xSignifier & 0x4000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000002C5C85FDF473DEA871F >> 128; } if (xSignifier & 0x2000000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000162E42FEFA39EF44D91 >> 128; } if (xSignifier & 0x1000000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000B17217F7D1CF79E949 >> 128; } if (xSignifier & 0x800000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000058B90BFBE8E7BCE544 >> 128; } if (xSignifier & 0x400000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000002C5C85FDF473DE6ECA >> 128; } if (xSignifier & 0x200000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000162E42FEFA39EF366F >> 128; } if (xSignifier & 0x100000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000B17217F7D1CF79AFA >> 128; } if (xSignifier & 0x80000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000058B90BFBE8E7BCD6D >> 128; } if (xSignifier & 0x40000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000002C5C85FDF473DE6B2 >> 128; } if (xSignifier & 0x20000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000162E42FEFA39EF358 >> 128; } if (xSignifier & 0x10000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000B17217F7D1CF79AB >> 128; } if (xSignifier & 0x8000000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000058B90BFBE8E7BCD5 >> 128; } if (xSignifier & 0x4000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000002C5C85FDF473DE6A >> 128; } if (xSignifier & 0x2000000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000162E42FEFA39EF34 >> 128; } if (xSignifier & 0x1000000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000B17217F7D1CF799 >> 128; } if (xSignifier & 0x800000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000058B90BFBE8E7BCC >> 128; } if (xSignifier & 0x400000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000002C5C85FDF473DE5 >> 128; } if (xSignifier & 0x200000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000162E42FEFA39EF2 >> 128; } if (xSignifier & 0x100000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000B17217F7D1CF78 >> 128; } if (xSignifier & 0x80000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000058B90BFBE8E7BB >> 128; } if (xSignifier & 0x40000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000002C5C85FDF473DD >> 128; } if (xSignifier & 0x20000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000162E42FEFA39EE >> 128; } if (xSignifier & 0x10000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000B17217F7D1CF6 >> 128; } if (xSignifier & 0x8000000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000058B90BFBE8E7A >> 128; } if (xSignifier & 0x4000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000002C5C85FDF473C >> 128; } if (xSignifier & 0x2000000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000162E42FEFA39D >> 128; } if (xSignifier & 0x1000000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000B17217F7D1CE >> 128; } if (xSignifier & 0x800000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000058B90BFBE8E6 >> 128; } if (xSignifier & 0x400000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000002C5C85FDF472 >> 128; } if (xSignifier & 0x200000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000162E42FEFA38 >> 128; } if (xSignifier & 0x100000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000B17217F7D1B >> 128; } if (xSignifier & 0x80000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000058B90BFBE8D >> 128; } if (xSignifier & 0x40000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000002C5C85FDF46 >> 128; } if (xSignifier & 0x20000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000162E42FEFA2 >> 128; } if (xSignifier & 0x10000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000B17217F7D0 >> 128; } if (xSignifier & 0x8000000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000058B90BFBE7 >> 128; } if (xSignifier & 0x4000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000002C5C85FDF3 >> 128; } if (xSignifier & 0x2000000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000162E42FEF9 >> 128; } if (xSignifier & 0x1000000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000B17217F7C >> 128; } if (xSignifier & 0x800000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000058B90BFBD >> 128; } if (xSignifier & 0x400000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000002C5C85FDE >> 128; } if (xSignifier & 0x200000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000162E42FEE >> 128; } if (xSignifier & 0x100000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000B17217F6 >> 128; } if (xSignifier & 0x80000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000058B90BFA >> 128; } if (xSignifier & 0x40000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000002C5C85FC >> 128; } if (xSignifier & 0x20000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000162E42FD >> 128; } if (xSignifier & 0x10000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000B17217E >> 128; } if (xSignifier & 0x8000000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000058B90BE >> 128; } if (xSignifier & 0x4000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000002C5C85E >> 128; } if (xSignifier & 0x2000000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000162E42E >> 128; } if (xSignifier & 0x1000000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000B17216 >> 128; } if (xSignifier & 0x800000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000058B90A >> 128; } if (xSignifier & 0x400000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000002C5C84 >> 128; } if (xSignifier & 0x200000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000162E41 >> 128; } if (xSignifier & 0x100000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000000B1720 >> 128; } if (xSignifier & 0x80000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000058B8F >> 128; } if (xSignifier & 0x40000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000002C5C7 >> 128; } if (xSignifier & 0x20000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000000162E3 >> 128; } if (xSignifier & 0x10000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000000B171 >> 128; } if (xSignifier & 0x8000 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000000058B8 >> 128; } if (xSignifier & 0x4000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000002C5B >> 128; } if (xSignifier & 0x2000 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000000162D >> 128; } if (xSignifier & 0x1000 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000000B16 >> 128; } if (xSignifier & 0x800 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000000058A >> 128; } if (xSignifier & 0x400 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000000002C4 >> 128; } if (xSignifier & 0x200 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000000161 >> 128; } if (xSignifier & 0x100 > 0) { resultSignifier = resultSignifier * 0x1000000000000000000000000000000B0 >> 128; } if (xSignifier & 0x80 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000000057 >> 128; } if (xSignifier & 0x40 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000000002B >> 128; } if (xSignifier & 0x20 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000000015 >> 128; } if (xSignifier & 0x10 > 0) { resultSignifier = resultSignifier * 0x10000000000000000000000000000000A >> 128; } if (xSignifier & 0x8 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000000004 >> 128; } if (xSignifier & 0x4 > 0) { resultSignifier = resultSignifier * 0x100000000000000000000000000000001 >> 128; } if (!xNegative) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent += 0x3FFF; } else if (resultExponent <= 0x3FFE) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent = 0x3FFF - resultExponent; } else { resultSignifier = resultSignifier >> resultExponent - 16367; resultExponent = 0; } return bytes16(uint128(resultExponent << 112 | resultSignifier)); } } } /** * Calculate e^x. * * @param x quadruple precision number * @return quadruple precision number */ function exp(bytes16 x) internal pure returns (bytes16) { unchecked { return pow_2(mul(x, 0x3FFF71547652B82FE1777D0FFDA0D23A)); } } /** * Get index of the most significant non-zero bit in binary representation of * x. Reverts if x is zero. * * @return index of the most significant non-zero bit in binary representation * of x */ function mostSignificantBit(uint256 x) private pure returns (uint256) { unchecked { require(x > 0); uint256 result = 0; if (x >= 0x100000000000000000000000000000000) { x >>= 128; result += 128; } if (x >= 0x10000000000000000) { x >>= 64; result += 64; } if (x >= 0x100000000) { x >>= 32; result += 32; } if (x >= 0x10000) { x >>= 16; result += 16; } if (x >= 0x100) { x >>= 8; result += 8; } if (x >= 0x10) { x >>= 4; result += 4; } if (x >= 0x4) { x >>= 2; result += 2; } if (x >= 0x2) result += 1; // No need to shift x anymore return result; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.15; interface IMinter { function mint(address _to, uint256 _projectId, address sender) external returns (uint256 _tokenId); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "@manifoldxyz/creator-core-solidity/=lib/creator-core-solidity/", "@manifoldxyz/libraries-solidity/=lib/libraries-solidity/", "@manifoldxyz/royalty-registry-solidity/=lib/royalty-registry-solidity/", "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "create2-helpers/=lib/royalty-registry-solidity/lib/create2-helpers/", "create2-scripts/=lib/royalty-registry-solidity/lib/create2-helpers/script/", "creator-core-solidity/=lib/creator-core-solidity/contracts/", "libraries-solidity/=lib/libraries-solidity/contracts/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "royalty-registry-solidity/=lib/royalty-registry-solidity/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IMinter","name":"passes_","type":"address"},{"internalType":"uint256","name":"startTime_","type":"uint256"},{"internalType":"uint256","name":"startPrice_","type":"uint256"},{"internalType":"uint256","name":"restPrice_","type":"uint256"},{"internalType":"uint256","name":"priceDropSlot_","type":"uint256"},{"internalType":"uint256","name":"halfPeriod_","type":"uint256"},{"internalType":"uint256","name":"maxMint_","type":"uint256"},{"internalType":"uint256","name":"projectId_","type":"uint256"},{"internalType":"address","name":"beneficiary_","type":"address"},{"internalType":"uint256","name":"freeMintStartTime_","type":"uint256"},{"internalType":"uint256","name":"freeMintDuration_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyStarted","type":"error"},{"inputs":[],"name":"Dissatisfied","type":"error"},{"inputs":[{"internalType":"address","name":"payee","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"FailedPaying","type":"error"},{"inputs":[],"name":"MintNotAvailable","type":"error"},{"inputs":[],"name":"NotYetStarted","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newMintPasses","type":"address"}],"name":"MintPassesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"open","type":"bool"}],"name":"MintPublicUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"purchaser","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"Purchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"BaseValue","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HalfPeriod","outputs":[{"internalType":"bytes16","name":"","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WHITELIST_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decayTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"freeMintDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"freeMintStartTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"halfPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRefund","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"minterType","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextPriceDrop","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"passes","outputs":[{"internalType":"contract IMinter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceDropSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"restPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxMint_","type":"uint256"}],"name":"setMaxMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMinter","name":"passes_","type":"address"}],"name":"setPasses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startPrice_","type":"uint256"},{"internalType":"uint256","name":"restPrice_","type":"uint256"},{"internalType":"uint256","name":"priceDropSlot_","type":"uint256"},{"internalType":"uint256","name":"halfPeriod_","type":"uint256"}],"name":"setPriceRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"projectId_","type":"uint256"}],"name":"setProjectId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startTime_","type":"uint256"},{"internalType":"uint256","name":"freeStartTime_","type":"uint256"},{"internalType":"uint256","name":"freeMintDuration_","type":"uint256"}],"name":"setStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"setWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFreeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelist","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620047a4380380620047a4833981016040819052620000349162000734565b6000805460ff1916905560016002556001600160a01b038b16620000b25760405162461bcd60e51b815260206004820152602a60248201527f5061737320636f6e7472616374206d757374206e6f7420626520746865207a65604482015269726f206164647265737360b01b60648201526084015b60405180910390fd5b428210156200011b5760405162461bcd60e51b815260206004820152602e60248201527f53746172742074696d6520666f722066726565206d696e742063616e6e6f742060448201526d1899481a5b881d1a19481c185cdd60921b6064820152608401620000a9565b62000127818b620007ce565b8214620001835760405162461bcd60e51b8152602060048201526024808201527f61756374696f6e206d757374206265206c61746572207468616e2066726565206044820152631b5a5b9d60e21b6064820152608401620000a9565b66038d7ea4c680008911620001f55760405162461bcd60e51b815260206004820152603160248201527f537461727420707269636520746f6f206c6f773a20636865636b2074686174206044820152707072696365732061726520696e2077656960781b6064820152608401620000a9565b66038d7ea4c680008811620002665760405162461bcd60e51b815260206004820152603060248201527f5265737420707269636520746f6f206c6f773a20636865636b2074686174207060448201526f72696365732061726520696e2077656960801b6064820152608401620000a9565b87891015620002ce5760405162461bcd60e51b815260206004820152602d60248201527f5374617274207072696365206d757374206e6f74206265206c6f77657220746860448201526c616e207265737420707269636560981b6064820152608401620000a9565b600087116200032f5760405162461bcd60e51b815260206004820152602660248201527f50726963652064726f7020736c6f74206d75737420626520677265617465722060448201526507468616e20360d41b6064820152608401620000a9565b600086116200038c5760405162461bcd60e51b815260206004820152602260248201527f48616c6620706572696f64206d7573742062652067726561746572207468616e604482015261020360f41b6064820152608401620000a9565b6001600160a01b038316620003f55760405162461bcd60e51b815260206004820152602860248201527f42656e6566696369617279206d757374206e6f7420626520746865207a65726f604482015267206164647265737360c01b6064820152608401620000a9565b60008511620004475760405162461bcd60e51b815260206004820152601f60248201527f4d6178206d696e74206d7573742062652067726561746572207468616e2030006044820152606401620000a9565b600580546001600160a01b03808e166001600160a01b03199283161790925560068c905560078b905560088a905560048990556009889055600c879055600f8054928616929091169190911790556010849055620004a58662000578565b600380546001600160801b03191660809290921c919091179055600754620004cd9062000578565b6003805460809290921c600160801b026001600160801b03909216919091179055601381905560128290556011805460ff191690556200050f600033620005e5565b6200053b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33620005e5565b620005677fdc72ed553f2544c34465af23b847953efeb813428162d767f9ba5f4013be676033620005e5565b5050505050505050505050620007f0565b6000816000036200058b57506000919050565b81600062000599826200066e565b90506070811015620005b4578060700382901b9150620005c8565b6070811115620005c8576070810382901c91505b613fff0160701b6001600160701b03919091161760801b92915050565b60008281526001602090815260408083206001600160a01b038516845290915290205460ff166200066a5760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45b5050565b60008082116200067d57600080fd5b6000600160801b83106200069357608092831c92015b680100000000000000008310620006ac57604092831c92015b6401000000008310620006c157602092831c92015b620100008310620006d457601092831c92015b6101008310620006e657600892831c92015b60108310620006f757600492831c92015b600483106200070857600292831c92015b6002831062000715576001015b92915050565b6001600160a01b03811681146200073157600080fd5b50565b60008060008060008060008060008060006101608c8e0312156200075757600080fd5b8b5162000764816200071b565b809b505060208c0151995060408c0151985060608c0151975060808c0151965060a08c0151955060c08c0151945060e08c015193506101008c0151620007aa816200071b565b809350506101208c015191506101408c015190509295989b509295989b9093969950565b818103818111156200071557634e487b7160e01b600052601160045260246000fd5b613fa480620008006000396000f3fe6080604052600436106102725760003560e01c80637501f7411161014f578063a217fddf116100c1578063d921eb781161007a578063d921eb78146106e8578063e394655614610702578063e45be8eb14610722578063e63ab1e914610738578063e9d1e8ac1461076c578063f1a9af89146107b757600080fd5b8063a217fddf14610648578063b8ee52891461065d578063ce9246dd1461067d578063d33fa1fe1461069d578063d547741f146106b2578063d56b3b9e146106d257600080fd5b806382cdb94f1161011357806382cdb94f146105915780638456cb59146105b157806391d14854146105c65780639b19251a146105e65780639cb15ad3146106135780639d1b464a1461063357600080fd5b80637501f7411461050657806378e979251461051c5780637a997ab7146105325780637b2784b0146105665780637c21143d1461057c57600080fd5b80633f4ba83a116101e85780635b70ea9f116101ac5780635b70ea9f1461044f5780635c975abb146104645780635cd768e31461047c578063611da053146104b65780637259c4e8146104cc57806372e77df5146104e657600080fd5b80633f4ba83a146103d95780633fafa127146103ee578063547520fe14610404578063590e1ae314610424578063591268851461043957600080fd5b80632f2ff15d1161023a5780632f2ff15d146103215780633197cbb614610341578063326e51511461035657806336568abe1461036c57806338af3eed1461038c5780633ccfd60b146103c457600080fd5b806301ffc9a7146102775780631249c58b146102ac57806318160ddd146102b6578063248a9ca3146102da5780632555cdd71461030b575b600080fd5b34801561028357600080fd5b50610297610292366004613acf565b6107cd565b60405190151581526020015b60405180910390f35b6102b4610804565b005b3480156102c257600080fd5b506102cc600a5481565b6040519081526020016102a3565b3480156102e657600080fd5b506102cc6102f5366004613af9565b6000908152600160208190526040909120015490565b34801561031757600080fd5b506102cc60095481565b34801561032d57600080fd5b506102b461033c366004613b27565b610a46565b34801561034d57600080fd5b506102cc610a71565b34801561036257600080fd5b506102cc60125481565b34801561037857600080fd5b506102b4610387366004613b27565b610a9a565b34801561039857600080fd5b50600f546103ac906001600160a01b031681565b6040516001600160a01b0390911681526020016102a3565b3480156103d057600080fd5b506102b4610b18565b3480156103e557600080fd5b506102b4610bc3565b3480156103fa57600080fd5b506102cc60105481565b34801561041057600080fd5b506102b461041f366004613af9565b610c2a565b34801561043057600080fd5b506102b4610cb1565b34801561044557600080fd5b506102cc600b5481565b34801561045b57600080fd5b506102b4610dbe565b34801561047057600080fd5b5060005460ff16610297565b34801561048857600080fd5b5060035461049d90600160801b900460801b81565b6040516001600160801b031990911681526020016102a3565b3480156104c257600080fd5b506102cc60135481565b3480156104d857600080fd5b5060035461049d9060801b81565b3480156104f257600080fd5b506102b4610501366004613b57565b610f85565b34801561051257600080fd5b506102cc600c5481565b34801561052857600080fd5b506102cc60065481565b34801561053e57600080fd5b506102cc7fdc72ed553f2544c34465af23b847953efeb813428162d767f9ba5f4013be676081565b34801561057257600080fd5b506102cc60045481565b34801561058857600080fd5b506102cc61121f565b34801561059d57600080fd5b506102b46105ac366004613b89565b611273565b3480156105bd57600080fd5b506102b4611330565b3480156105d257600080fd5b506102976105e1366004613b27565b611369565b3480156105f257600080fd5b506102cc610601366004613b89565b60176020526000908152604090205481565b34801561061f57600080fd5b506102b461062e366004613ba6565b611394565b34801561063f57600080fd5b506102cc611497565b34801561065457600080fd5b506102cc600081565b34801561066957600080fd5b506005546103ac906001600160a01b031681565b34801561068957600080fd5b506102b4610698366004613af9565b611530565b3480156106a957600080fd5b506102cc611567565b3480156106be57600080fd5b506102b46106cd366004613b27565b6115d7565b3480156106de57600080fd5b506102cc60085481565b3480156106f457600080fd5b506011546102979060ff1681565b34801561070e57600080fd5b506102b461071d366004613ca8565b6115fd565b34801561072e57600080fd5b506102cc60145481565b34801561074457600080fd5b506102cc7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b34801561077857600080fd5b506107aa60405180604001604052806012815260200171223aba31b420bab1ba34b7b726b4b73a32b960711b81525081565b6040516102a39190613dba565b3480156107c357600080fd5b506102cc60075481565b60006001600160e01b03198216637965db0b60e01b14806107fe57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61080c611674565b610829576040516303bdb9df60e61b815260040160405180910390fd5b61083161169a565b6108396116e0565b346000610844611497565b9050808210156108925760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b60448201526064015b60405180910390fd5b600c54600a54106108dc5760405162461bcd60e51b815260206004820152601460248201527313585e1a5b5d5b481b5a5b9d081c995858da195960621b6044820152606401610889565b336000908152601560205260409020541580156108fa575060085482115b1561094257601680546001810182556000919091527fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b51242890180546001600160a01b031916331790555b336000818152601560205260408082208054600190810182559081018054870190556014859055600a805490910190556005546010549151630d4d151360e01b8152600481018590526024810192909252604482019390935290916001600160a01b031690630d4d1513906064016020604051808303816000875af11580156109cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f39190613dcd565b60408051338152602081018390529081018590529091507f12cb4648cf3058b17ceeb33e579f8b0bc269fe0843f3900b8e24b6c54871703c9060600160405180910390a1505050610a446001600255565b565b60008281526001602081905260409091200154610a6281611737565b610a6c8383611741565b505050565b6000600e54610a7e611567565b600654610a8b9190613dfc565b610a959190613dfc565b905090565b6001600160a01b0381163314610b0a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610889565b610b1482826117ac565b5050565b6000610b2381611737565b610b2b6116e0565b600f54604051479160009182916001600160a01b03169084908381818185875af1925050503d8060008114610b7c576040519150601f19603f3d011682016040523d82523d6000602084013e610b81565b606091505b509150915081610bb357600f5460405163cd797a4160e01b8152610889916001600160a01b0316908390600401613e0f565b505050610bc06001600255565b50565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610bed81611737565b610bf5611813565b600654421115610bc057600654600d541015610c16576006544203600e5550565b50600d54600e805442929092039091019055565b610c32611674565b15610c5057604051631fbde44560e01b815260040160405180910390fd5b6000610c5b81611737565b60008211610cab5760405162461bcd60e51b815260206004820152601f60248201527f4d6178206d696e74206d7573742062652067726561746572207468616e2030006044820152606401610889565b50600c55565b610cb961169a565b6000610cc481611737565b60115460ff1615610d065760405162461bcd60e51b815260206004820152600c60248201526b1a185cc81c99599d5b99195960a21b6044820152606401610889565b6011805460ff19166001179055600080805b601654811015610db85760168181548110610d3557610d35613e3b565b60009182526020808320909101546014546001600160a01b039091168084526015909252604090922054909350610d6c9190613e51565b6001600160a01b038316600090815260156020526040902060010154610d929190613e68565b92508215610da65760008060008086865af1505b80610db081613e7b565b915050610d18565b50505050565b610dc661169a565b610dce6116e0565b4260125411158015610dee575042601354601254610dec9190613dfc565b115b610e305760405162461bcd60e51b8152602060048201526013602482015272199c9959481b5a5b9d081b9bdd081d985b1a59606a1b6044820152606401610889565b336000908152601760205260408120549003610e5f57604051634e4e22b360e01b815260040160405180910390fd5b60005b33600090815260176020526040902054811015610f5457600554601054604051630d4d151360e01b81523360048201819052602482019290925260448101919091526000916001600160a01b031690630d4d1513906064016020604051808303816000875af1158015610ed9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efd9190613dcd565b604080513381526020810183905260008183015290519192507f12cb4648cf3058b17ceeb33e579f8b0bc269fe0843f3900b8e24b6c54871703c919081900360600190a15080610f4c81613e7b565b915050610e62565b503360009081526017602052604081208054600b805490910190558054600a8054909101905555610a446001600255565b610f8d611674565b15610fab57604051631fbde44560e01b815260040160405180910390fd5b6000610fb681611737565b66038d7ea4c6800085116110265760405162461bcd60e51b815260206004820152603160248201527f537461727420707269636520746f6f206c6f773a20636865636b2074686174206044820152707072696365732061726520696e2077656960781b6064820152608401610889565b66038d7ea4c6800084116110955760405162461bcd60e51b815260206004820152603060248201527f5265737420707269636520746f6f206c6f773a20636865636b2074686174207060448201526f72696365732061726520696e2077656960801b6064820152608401610889565b838510156110fb5760405162461bcd60e51b815260206004820152602d60248201527f5374617274207072696365206d757374206e6f74206265206c6f77657220746860448201526c616e207265737420707269636560981b6064820152608401610889565b6000831161115a5760405162461bcd60e51b815260206004820152602660248201527f50726963652064726f7020736c6f74206d75737420626520677265617465722060448201526507468616e20360d41b6064820152608401610889565b600082116111b55760405162461bcd60e51b815260206004820152602260248201527f48616c6620706572696f64206d7573742062652067726561746572207468616e604482015261020360f41b6064820152608401610889565b60078590556008849055600483905560098290556111d282611865565b600380546001600160801b03191660809290921c9190911790556007546111f890611865565b600360106101000a8154816001600160801b03021916908360801c02179055505050505050565b6000611229611674565b61123d57600454600654610a959190613dfc565b600060045461124a6118cc565b6112549190613eaa565b6004546112619190613e68565b905061126d8142613dfc565b91505090565b61127b611674565b1561129957604051631fbde44560e01b815260040160405180910390fd5b60006112a481611737565b6001600160a01b03821661130d5760405162461bcd60e51b815260206004820152602a60248201527f5061737320636f6e7472616374206d757374206e6f7420626520746865207a65604482015269726f206164647265737360b01b6064820152608401610889565b50600580546001600160a01b0319166001600160a01b0392909216919091179055565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a61135a81611737565b611362611906565b5042600d55565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61139c611674565b156113ba57604051631fbde44560e01b815260040160405180910390fd5b60006113c581611737565b428310156114215760405162461bcd60e51b8152602060048201526024808201527f4e65772073746172742074696d652063616e6e6f7420626520696e20746865206044820152631c185cdd60e21b6064820152608401610889565b61142b8285613e68565b83146114855760405162461bcd60e51b8152602060048201526024808201527f61756374696f6e206d757374206265206c61746572207468616e2066726565206044820152631b5a5b9d60e21b6064820152608401610889565b50600692909255601391909155601255565b6000806114a26118cc565b905060045460045482816114b8576114b8613e94565b0402905060006114c782611865565b6003549091506000906114de90839060801b611943565b905060006114eb82611c0a565b60035490915060009061150890600160801b900460801b83611943565b9050600061151582612f60565b905060085481101561152657506008545b9695505050505050565b611538611674565b1561155657604051631fbde44560e01b815260040160405180910390fd5b600061156181611737565b50601055565b600354600090819061158290600160801b900460801b612fe4565b90506000611599611594600854611865565b612fe4565b6003549091506000906115b89060801b6115b3858561319c565b6131ae565b905060006115c582612f60565b600a9081018190040295945050505050565b600082815260016020819052604090912001546115f381611737565b610a6c83836117ac565b7fdc72ed553f2544c34465af23b847953efeb813428162d767f9ba5f4013be676061162781611737565b8251825180820361166d57602085016020850160005b84811015611669576020818102848101519084015160009182526017909252604090205560010161163d565b5050505b5050505050565b600060065461168560005460ff1690565b61168f5742611693565b600d545b1015905090565b60005460ff1615610a445760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610889565b60028054036117315760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610889565b60028055565b610bc08133613417565b61174b8282611369565b610b145760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b6117b68282611369565b15610b145760008281526001602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b61181b613470565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60008160000361187757506000919050565b816000611883826134b9565b9050607081101561189c578060700382901b91506118af565b60708111156118af576070810382901c91505b613fff0160701b6001600160701b03919091161760801b92915050565b60006118d6611674565b6118e05750600090565b60005460ff166118f75750600e5460065442030390565b50600e54600654600d54030390565b61190e61169a565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586118483390565b6000617fff60f084811c8216919084901c8116908290036119885780617fff03611977575061ffff60ef1b91506107fe9050565b505050600160ff1b811682186107fe565b80617fff036119cb576dffffffffffffffffffffffffffff60801b8416156119ba575061ffff60ef1b91506107fe9050565b505050808218600160ff1b166107fe565b600160801b600160ff1b038416600003611a1b57600160801b600160ff1b038516600003611a03575061ffff60ef1b91506107fe9050565b505050808218600160ff1b16617fff60f01b176107fe565b6001600160701b03608085901c166000829003611a3b5760019150611a42565b600160701b175b6001600160701b03608087901c166000849003611a85578015611a80576000611a6a826134b9565b6001955060e20393840160711901939190911b90505b611a8f565b600160701b1760721b5b818181611a9e57611a9e613e94565b04905080600003611ace57600160ff1b87871816611abd576000611ac3565b600160ff1b5b9450505050506107fe565b6001606c1b811015611ae257611ae2613ecc565b6000600160731b821015611b2157600160721b821015611b1657600160711b821015611b0f576070611b19565b6071611b19565b60725b60ff16611b2a565b611b2a826134b9565b905083614071018186011115611b4857617fff945060009150611bdb565b83818601613ffc011015611b63576000945060009150611bdb565b83818601613f8c011015611bb0578385613ffc011115611b8e578385613ffc010382901b9150611ba7565b8385613ffc011015611ba757613ffc8585030382901c91505b60009450611bdb565b6070811115611bc3576070810382901c91505b6001600160701b038216915083818601613f8d010394505b81607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b955050505050506107fe565b60006001607f1b608083901c90811190617fff60f085901c8116916001600160701b03169082148015611c3c57508015155b15611c50575061ffff60ef1b949350505050565b61400d821115611c765782611c6a57617fff60f01b611c6d565b60005b95945050505050565b613f7f821015611c8f5750613fff60f01b949350505050565b81600003611ca05760019150611ca7565b600160701b175b613fef821115611cbd57613fee1982011b611ccf565b613fef821015611ccf57613fef8290031c5b828015611ce0575061203760811b81115b15611cf057506000949350505050565b82158015611d0f5750713fffffffffffffffffffffffffffffffffff81115b15611d235750617fff60f01b949350505050565b6001600160801b0381169060801c838015611d3d57508115155b15611d49579019906001015b6001607f1b82811615611d6d5770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b6001607e1b831615611d90577001306fe0a31b7152de8d5a46305c85edec0260801c5b6001607d1b831615611db3577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b6001607c1b831615611dd65770010b5586cf9890f6298b92b71842a983630260801c5b6001607b1b831615611df9577001059b0d31585743ae7c548eb68ca417fd0260801c5b6001607a1b831615611e1c57700102c9a3e778060ee6f7caca4f7a29bde80260801c5b600160791b831615611e3f5770010163da9fb33356d84a66ae336dcdfa3f0260801c5b600160781b831615611e6257700100b1afa5abcbed6129ab13ec11dc95430260801c5b600160771b831615611e855770010058c86da1c09ea1ff19d294cf2f679b0260801c5b600160761b831615611ea8577001002c605e2e8cec506d21bfc89a23a00f0260801c5b600160751b831615611ecb57700100162f3904051fa128bca9c55c31e5df0260801c5b600160741b831615611eee577001000b175effdc76ba38e31671ca9397250260801c5b600160731b831615611f1157700100058ba01fb9f96d6cacd4b180917c3d0260801c5b600160721b831615611f345770010002c5cc37da9491d0985c348c68e7b30260801c5b600160711b831615611f57577001000162e525ee054754457d59952920260260801c5b600160701b831615611f7a5770010000b17255775c040618bf4a4ade83fc0260801c5b6001606f1b831615611f9d577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6001606e1b831615611fc057700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6001606d1b831615611fe35770010000162e43f4f831060e02d839a9d16d0260801c5b6001606c1b83161561200657700100000b1721bcfc99d9f890ea069117630260801c5b6001606b1b8316156120295770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6001606a1b83161561204c577001000002c5c863b73f016468f6bac5ca2b0260801c5b600160691b83161561206f57700100000162e430e5a18f6119e3c02282a50260801c5b600160681b831615612092577001000000b1721835514b86e6d96efd1bfe0260801c5b600160671b8316156120b557700100000058b90c0b48c6be5df846c5b2ef0260801c5b600160661b8316156120d85770010000002c5c8601cc6b9e94213c72737a0260801c5b600160651b8316156120fb577001000000162e42fff037df38aa2b219f060260801c5b600160641b83161561211e5770010000000b17217fba9c739aa5819f44f90260801c5b600160631b831615612141577001000000058b90bfcdee5acd3c1cedc8230260801c5b600160621b83161561216457700100000002c5c85fe31f35a6a30da1be500260801c5b600160611b8316156121875770010000000162e42ff0999ce3541b9fffcf0260801c5b600160601b8316156121aa57700100000000b17217f80f4ef5aadda455540260801c5b6001605f1b8316156121cd5770010000000058b90bfbf8479bd5a81b51ad0260801c5b6001605e1b8316156121f0577001000000002c5c85fdf84bd62ae30a74cc0260801c5b6001605d1b83161561221357700100000000162e42fefb2fed257559bdaa0260801c5b6001605c1b831615612236577001000000000b17217f7d5a7716bba4a9ae0260801c5b6001605b1b83161561225957700100000000058b90bfbe9ddbac5e109cce0260801c5b6001605a1b83161561227c5770010000000002c5c85fdf4b15de6f17eb0d0260801c5b600160591b83161561229f577001000000000162e42fefa494f1478fde050260801c5b600160581b8316156122c25770010000000000b17217f7d20cf927c8e94c0260801c5b600160571b8316156122e5577001000000000058b90bfbe8f71cb4e4b33d0260801c5b600160561b83161561230857700100000000002c5c85fdf477b662b269450260801c5b600160551b83161561232b5770010000000000162e42fefa3ae53369388c0260801c5b600160541b83161561234e57700100000000000b17217f7d1d351a389d400260801c5b600160531b8316156123715770010000000000058b90bfbe8e8b2d3d4ede0260801c5b600160521b831615612394577001000000000002c5c85fdf4741bea6e77e0260801c5b600160511b8316156123b757700100000000000162e42fefa39fe95583c20260801c5b600160501b8316156123da577001000000000000b17217f7d1cfb72b45e10260801c5b698000000000000000000083161561240357700100000000000058b90bfbe8e7cc35c3f00260801c5b694000000000000000000083161561242c5770010000000000002c5c85fdf473e242ea380260801c5b6920000000000000000000831615612455577001000000000000162e42fefa39f02b772c0260801c5b691000000000000000000083161561247e5770010000000000000b17217f7d1cf7d83c1a0260801c5b69080000000000000000008316156124a7577001000000000000058b90bfbe8e7bdcbe2e0260801c5b69040000000000000000008316156124d057700100000000000002c5c85fdf473dea871f0260801c5b69020000000000000000008316156124f95770010000000000000162e42fefa39ef44d910260801c5b690100000000000000000083161561252257700100000000000000b17217f7d1cf79e9490260801c5b6880000000000000000083161561254a5770010000000000000058b90bfbe8e7bce5440260801c5b68400000000000000000831615612572577001000000000000002c5c85fdf473de6eca0260801c5b6820000000000000000083161561259a57700100000000000000162e42fefa39ef366f0260801c5b681000000000000000008316156125c2577001000000000000000b17217f7d1cf79afa0260801c5b680800000000000000008316156125ea57700100000000000000058b90bfbe8e7bcd6d0260801c5b680400000000000000008316156126125770010000000000000002c5c85fdf473de6b20260801c5b6802000000000000000083161561263a577001000000000000000162e42fefa39ef3580260801c5b600160401b83161561265d5770010000000000000000b17217f7d1cf79ab0260801c5b678000000000000000831615612684577001000000000000000058b90bfbe8e7bcd50260801c5b6740000000000000008316156126ab57700100000000000000002c5c85fdf473de6a0260801c5b6720000000000000008316156126d25770010000000000000000162e42fefa39ef340260801c5b6710000000000000008316156126f957700100000000000000000b17217f7d1cf7990260801c5b6708000000000000008316156127205770010000000000000000058b90bfbe8e7bcc0260801c5b670400000000000000831615612747577001000000000000000002c5c85fdf473de50260801c5b67020000000000000083161561276e57700100000000000000000162e42fefa39ef20260801c5b670100000000000000831615612795577001000000000000000000b17217f7d1cf780260801c5b66800000000000008316156127bb57700100000000000000000058b90bfbe8e7bb0260801c5b66400000000000008316156127e15770010000000000000000002c5c85fdf473dd0260801c5b6620000000000000831615612807577001000000000000000000162e42fefa39ee0260801c5b661000000000000083161561282d5770010000000000000000000b17217f7d1cf60260801c5b6608000000000000831615612853577001000000000000000000058b90bfbe8e7a0260801c5b660400000000000083161561287957700100000000000000000002c5c85fdf473c0260801c5b660200000000000083161561289f5770010000000000000000000162e42fefa39d0260801c5b66010000000000008316156128c557700100000000000000000000b17217f7d1ce0260801c5b658000000000008316156128ea5770010000000000000000000058b90bfbe8e60260801c5b6540000000000083161561290f577001000000000000000000002c5c85fdf4720260801c5b6520000000000083161561293457700100000000000000000000162e42fefa380260801c5b65100000000000831615612959577001000000000000000000000b17217f7d1b0260801c5b6508000000000083161561297e57700100000000000000000000058b90bfbe8d0260801c5b650400000000008316156129a35770010000000000000000000002c5c85fdf460260801c5b650200000000008316156129c8577001000000000000000000000162e42fefa20260801c5b650100000000008316156129ed5770010000000000000000000000b17217f7d00260801c5b648000000000831615612a11577001000000000000000000000058b90bfbe70260801c5b644000000000831615612a3557700100000000000000000000002c5c85fdf30260801c5b642000000000831615612a595770010000000000000000000000162e42fef90260801c5b641000000000831615612a7d57700100000000000000000000000b17217f7c0260801c5b640800000000831615612aa15770010000000000000000000000058b90bfbd0260801c5b640400000000831615612ac5577001000000000000000000000002c5c85fde0260801c5b640200000000831615612ae957700100000000000000000000000162e42fee0260801c5b640100000000831615612b0d577001000000000000000000000000b17217f60260801c5b6380000000831615612b3057700100000000000000000000000058b90bfa0260801c5b6340000000831615612b535770010000000000000000000000002c5c85fc0260801c5b6320000000831615612b76577001000000000000000000000000162e42fd0260801c5b6310000000831615612b995770010000000000000000000000000b17217e0260801c5b6308000000831615612bbc577001000000000000000000000000058b90be0260801c5b6304000000831615612bdf57700100000000000000000000000002c5c85e0260801c5b6302000000831615612c025770010000000000000000000000000162e42e0260801c5b6301000000831615612c2557700100000000000000000000000000b172160260801c5b62800000831615612c475770010000000000000000000000000058b90a0260801c5b62400000831615612c69577001000000000000000000000000002c5c840260801c5b62200000831615612c8b57700100000000000000000000000000162e410260801c5b62100000831615612cad577001000000000000000000000000000b17200260801c5b62080000831615612ccf57700100000000000000000000000000058b8f0260801c5b62040000831615612cf15770010000000000000000000000000002c5c70260801c5b62020000831615612d13577001000000000000000000000000000162e30260801c5b62010000831615612d355770010000000000000000000000000000b1710260801c5b618000831615612d56577001000000000000000000000000000058b80260801c5b614000831615612d7757700100000000000000000000000000002c5b0260801c5b612000831615612d985770010000000000000000000000000000162d0260801c5b611000831615612db957700100000000000000000000000000000b160260801c5b610800831615612dda5770010000000000000000000000000000058a0260801c5b610400831615612dfb577001000000000000000000000000000002c40260801c5b610200831615612e1c577001000000000000000000000000000001610260801c5b610100831615612e3d577001000000000000000000000000000000b00260801c5b6080831615612e5d577001000000000000000000000000000000570260801c5b6040831615612e7d5770010000000000000000000000000000002b0260801c5b6020831615612e9d577001000000000000000000000000000000150260801c5b6010831615612ebd5770010000000000000000000000000000000a0260801c5b6008831615612edd577001000000000000000000000000000000040260801c5b6004831615612efd577001000000000000000000000000000000010260801c5b84612f1e57600f81901c6001600160701b03169050613fff82019150612f4d565b613ffe8211612f4357600f81901c6001600160701b0316905081613fff039150612f4d565b600091613fee19011c5b60709190911b1760801b95945050505050565b6000617fff60f083901c16613fff811015612f7e5750600092915050565b6001607f1b608084901c10612f9257600080fd5b6140fe811115612fa157600080fd5b600160701b6001600160701b03608085901c161761406f821015612fcb5761406f8290031c612fdd565b61406f821115612fdd5761406e1982011b5b9392505050565b60006001607f1b608083901c1115613002575061ffff60ef1b919050565b6001600160801b03198216613fff60f01b0361302057506000919050565b617fff60f083901c811690819003613039575090919050565b6001600160701b03608084901c1660008290036130595760019150613060565b600160701b175b8060000361307957506001600160f01b03199392505050565b600061406f81613fff851061309f5750600f9290921b9160009150613ffe1984016130de565b60019250600160701b84106130c15784613ffe039050600f84901b93506130de565b60006130cc856134b9565b607f8190039590951b9461406d039150505b836001607f1b036131145782156130f3576001015b60006130fe826134b9565b60700390508082901b9150808303925050613162565b600083613122576000613125565b60015b60ff1690505b600160701b8210156131605793800260ff81901c607f81019190911c94600019939093019260019290921b908218019061312b565b505b806001600160701b0316607083901b8461317d576000613183565b6001607f1b5b6001600160801b0316171760801b979650505050505050565b6000612fdd83600160ff1b8418613557565b6000617fff60f084811c8216919084901c81169082900361324d5780617fff03613229576001600160801b0319808516908616036131f757505050600160ff1b811682186107fe565b6001600160801b031985851816600160ff1b03613219575050508181176107fe565b5061ffff60ef1b91506107fe9050565b600160801b600160ff1b038416600003611977575061ffff60ef1b91506107fe9050565b80617fff0361328b57600160801b600160ff1b03851660000361327a575061ffff60ef1b91506107fe9050565b505050600160ff1b821681186107fe565b6001600160701b03608086901c1660008390036132ab57600192506132b2565b600160701b175b6001600160701b03608086901c1660008390036132d257600192506132d9565b600160701b175b8082029150816000036132fa57600160ff1b87871816611abd576000611ac3565b928201926000600160e11b83101561332d57600160e01b83101561332657613321836134b9565b613330565b60e0613330565b60e15b9050614070818601101561334b5760009450600092506133e8565b6140e0818601101561338e5761407085101561337057846140700383901c9250613385565b61407085111561338557614070850383901b92505b600094506133e8565b61c0dd81860111156133a857617fff9450600092506133e8565b60708111156133bf576070810383901c92506133d2565b60708110156133d2578060700383901b92505b6001600160701b03831692506140df8186010394505b82607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b955050505050506107fe565b6134218282611369565b610b145761342e81613921565b613439836020613933565b60405160200161344a929190613ee2565b60408051601f198184030181529082905262461bcd60e51b825261088991600401613dba565b60005460ff16610a445760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610889565b60008082116134c757600080fd5b6000600160801b83106134dc57608092831c92015b600160401b83106134ef57604092831c92015b640100000000831061350357602092831c92015b62010000831061351557601092831c92015b610100831061352657600892831c92015b6010831061353657600492831c92015b6004831061354657600292831c92015b600283106107fe5760010192915050565b6000617fff60f084811c8216919084901c8116908290036135a35780617fff03613599576001600160801b0319808516908616036132195784925050506107fe565b84925050506107fe565b80617fff036135b65783925050506107fe565b6001607f1b608086901c90811015906001600160701b031660008490036135e057600193506135e7565b600160701b175b6001607f1b608087901c90811015906001600160701b031660008590036136115760019450613618565b600160701b175b8260000361364b576001600160801b03198816600160ff1b1461363b578761363e565b60005b96505050505050506107fe565b8060000361366e576001600160801b03198916600160ff1b1461363b578861363e565b8486038215158515150361377757607081131561369457899750505050505050506107fe565b60008113156136a65790811c906136d5565b606f198112156136bf57889750505050505050506107fe565b60008112156136d5578060000384901c93508596505b92810192600160711b84106136f0576001968701969390931c925b86617fff03613721578461370957617fff60f01b613713565b6001600160f01b03195b9750505050505050506107fe565b600160701b8410156137365760009650613743565b6001600160701b03841693505b83607088901b8661375557600061375b565b6001607f1b5b6001600160801b0316171760801b9750505050505050506107fe565b600081131561379257600184901b93506001870396506137a9565b60008112156137a957600182901b91506001860396505b60708113156137bb5760019150613808565b60018113156137d8576001810360018303901c6001019150613808565b606f198112156137eb5760019350613808565b600019811215613808576001816000030360018503901c60010193505b818410613819578184039350613822565b83820393508294505b8360000361383b5750600096506107fe95505050505050565b6000613846856134b9565b90508060710361386b57600185901c6001600160701b031694506001880197506138ba565b60708110156138ad5760708190038089111561389a578086901b6001600160701b0316955080890398506138a7565b600098600019019590951b945b506138ba565b6001600160701b03851694505b87617fff036138ec57856138d357617fff60f01b6138dd565b6001600160f01b03195b985050505050505050506107fe565b84607089901b876138fe576000613904565b6001607f1b5b6001600160801b0316171760801b985050505050505050506107fe565b60606107fe6001600160a01b03831660145b60606000613942836002613e51565b61394d906002613dfc565b67ffffffffffffffff81111561396557613965613bd2565b6040519080825280601f01601f19166020018201604052801561398f576020820181803683370190505b509050600360fc1b816000815181106139aa576139aa613e3b565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106139d9576139d9613e3b565b60200101906001600160f81b031916908160001a90535060006139fd846002613e51565b613a08906001613dfc565b90505b6001811115613a80576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613a3c57613a3c613e3b565b1a60f81b828281518110613a5257613a52613e3b565b60200101906001600160f81b031916908160001a90535060049490941c93613a7981613f57565b9050613a0b565b508315612fdd5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610889565b600060208284031215613ae157600080fd5b81356001600160e01b031981168114612fdd57600080fd5b600060208284031215613b0b57600080fd5b5035919050565b6001600160a01b0381168114610bc057600080fd5b60008060408385031215613b3a57600080fd5b823591506020830135613b4c81613b12565b809150509250929050565b60008060008060808587031215613b6d57600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215613b9b57600080fd5b8135612fdd81613b12565b600080600060608486031215613bbb57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c1157613c11613bd2565b604052919050565b600067ffffffffffffffff821115613c3357613c33613bd2565b5060051b60200190565b600082601f830112613c4e57600080fd5b81356020613c63613c5e83613c19565b613be8565b82815260059290921b84018101918181019086841115613c8257600080fd5b8286015b84811015613c9d5780358352918301918301613c86565b509695505050505050565b60008060408385031215613cbb57600080fd5b823567ffffffffffffffff80821115613cd357600080fd5b818501915085601f830112613ce757600080fd5b81356020613cf7613c5e83613c19565b82815260059290921b84018101918181019089841115613d1657600080fd5b948201945b83861015613d3d578535613d2e81613b12565b82529482019490820190613d1b565b96505086013592505080821115613d5357600080fd5b50613d6085828601613c3d565b9150509250929050565b60005b83811015613d85578181015183820152602001613d6d565b50506000910152565b60008151808452613da6816020860160208601613d6a565b601f01601f19169290920160200192915050565b602081526000612fdd6020830184613d8e565b600060208284031215613ddf57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156107fe576107fe613de6565b6001600160a01b0383168152604060208201819052600090613e3390830184613d8e565b949350505050565b634e487b7160e01b600052603260045260246000fd5b80820281158282048414176107fe576107fe613de6565b818103818111156107fe576107fe613de6565b600060018201613e8d57613e8d613de6565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082613ec757634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052600160045260246000fd5b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613f1a816017850160208801613d6a565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613f4b816028840160208801613d6a565b01602801949350505050565b600081613f6657613f66613de6565b50600019019056fea2646970667358221220d3532ca450f4fc1392af2c734e14b40ab7d0fbe2b307af78ee058290054ea20864736f6c634300081500330000000000000000000000008cdbd7010bd197848e95c1fd7f6e870aac9b0d3c0000000000000000000000000000000000000000000000000000000065392d7000000000000000000000000000000000000000000000000029a2241af62c000000000000000000000000000000000000000000000000000001aa535d3d0c0000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000030700000000000000000000000000000000000000000000000000000000000006a400000000000000000000000000000000000000000000000000000000000000020000000000000000000000006b15fd9cc33dd0852f80567549e552d20a5bdce30000000000000000000000000000000000000000000000000000000065391f600000000000000000000000000000000000000000000000000000000000000e10
Deployed Bytecode
0x6080604052600436106102725760003560e01c80637501f7411161014f578063a217fddf116100c1578063d921eb781161007a578063d921eb78146106e8578063e394655614610702578063e45be8eb14610722578063e63ab1e914610738578063e9d1e8ac1461076c578063f1a9af89146107b757600080fd5b8063a217fddf14610648578063b8ee52891461065d578063ce9246dd1461067d578063d33fa1fe1461069d578063d547741f146106b2578063d56b3b9e146106d257600080fd5b806382cdb94f1161011357806382cdb94f146105915780638456cb59146105b157806391d14854146105c65780639b19251a146105e65780639cb15ad3146106135780639d1b464a1461063357600080fd5b80637501f7411461050657806378e979251461051c5780637a997ab7146105325780637b2784b0146105665780637c21143d1461057c57600080fd5b80633f4ba83a116101e85780635b70ea9f116101ac5780635b70ea9f1461044f5780635c975abb146104645780635cd768e31461047c578063611da053146104b65780637259c4e8146104cc57806372e77df5146104e657600080fd5b80633f4ba83a146103d95780633fafa127146103ee578063547520fe14610404578063590e1ae314610424578063591268851461043957600080fd5b80632f2ff15d1161023a5780632f2ff15d146103215780633197cbb614610341578063326e51511461035657806336568abe1461036c57806338af3eed1461038c5780633ccfd60b146103c457600080fd5b806301ffc9a7146102775780631249c58b146102ac57806318160ddd146102b6578063248a9ca3146102da5780632555cdd71461030b575b600080fd5b34801561028357600080fd5b50610297610292366004613acf565b6107cd565b60405190151581526020015b60405180910390f35b6102b4610804565b005b3480156102c257600080fd5b506102cc600a5481565b6040519081526020016102a3565b3480156102e657600080fd5b506102cc6102f5366004613af9565b6000908152600160208190526040909120015490565b34801561031757600080fd5b506102cc60095481565b34801561032d57600080fd5b506102b461033c366004613b27565b610a46565b34801561034d57600080fd5b506102cc610a71565b34801561036257600080fd5b506102cc60125481565b34801561037857600080fd5b506102b4610387366004613b27565b610a9a565b34801561039857600080fd5b50600f546103ac906001600160a01b031681565b6040516001600160a01b0390911681526020016102a3565b3480156103d057600080fd5b506102b4610b18565b3480156103e557600080fd5b506102b4610bc3565b3480156103fa57600080fd5b506102cc60105481565b34801561041057600080fd5b506102b461041f366004613af9565b610c2a565b34801561043057600080fd5b506102b4610cb1565b34801561044557600080fd5b506102cc600b5481565b34801561045b57600080fd5b506102b4610dbe565b34801561047057600080fd5b5060005460ff16610297565b34801561048857600080fd5b5060035461049d90600160801b900460801b81565b6040516001600160801b031990911681526020016102a3565b3480156104c257600080fd5b506102cc60135481565b3480156104d857600080fd5b5060035461049d9060801b81565b3480156104f257600080fd5b506102b4610501366004613b57565b610f85565b34801561051257600080fd5b506102cc600c5481565b34801561052857600080fd5b506102cc60065481565b34801561053e57600080fd5b506102cc7fdc72ed553f2544c34465af23b847953efeb813428162d767f9ba5f4013be676081565b34801561057257600080fd5b506102cc60045481565b34801561058857600080fd5b506102cc61121f565b34801561059d57600080fd5b506102b46105ac366004613b89565b611273565b3480156105bd57600080fd5b506102b4611330565b3480156105d257600080fd5b506102976105e1366004613b27565b611369565b3480156105f257600080fd5b506102cc610601366004613b89565b60176020526000908152604090205481565b34801561061f57600080fd5b506102b461062e366004613ba6565b611394565b34801561063f57600080fd5b506102cc611497565b34801561065457600080fd5b506102cc600081565b34801561066957600080fd5b506005546103ac906001600160a01b031681565b34801561068957600080fd5b506102b4610698366004613af9565b611530565b3480156106a957600080fd5b506102cc611567565b3480156106be57600080fd5b506102b46106cd366004613b27565b6115d7565b3480156106de57600080fd5b506102cc60085481565b3480156106f457600080fd5b506011546102979060ff1681565b34801561070e57600080fd5b506102b461071d366004613ca8565b6115fd565b34801561072e57600080fd5b506102cc60145481565b34801561074457600080fd5b506102cc7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b34801561077857600080fd5b506107aa60405180604001604052806012815260200171223aba31b420bab1ba34b7b726b4b73a32b960711b81525081565b6040516102a39190613dba565b3480156107c357600080fd5b506102cc60075481565b60006001600160e01b03198216637965db0b60e01b14806107fe57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61080c611674565b610829576040516303bdb9df60e61b815260040160405180910390fd5b61083161169a565b6108396116e0565b346000610844611497565b9050808210156108925760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b60448201526064015b60405180910390fd5b600c54600a54106108dc5760405162461bcd60e51b815260206004820152601460248201527313585e1a5b5d5b481b5a5b9d081c995858da195960621b6044820152606401610889565b336000908152601560205260409020541580156108fa575060085482115b1561094257601680546001810182556000919091527fd833147d7dc355ba459fc788f669e58cfaf9dc25ddcd0702e87d69c7b51242890180546001600160a01b031916331790555b336000818152601560205260408082208054600190810182559081018054870190556014859055600a805490910190556005546010549151630d4d151360e01b8152600481018590526024810192909252604482019390935290916001600160a01b031690630d4d1513906064016020604051808303816000875af11580156109cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f39190613dcd565b60408051338152602081018390529081018590529091507f12cb4648cf3058b17ceeb33e579f8b0bc269fe0843f3900b8e24b6c54871703c9060600160405180910390a1505050610a446001600255565b565b60008281526001602081905260409091200154610a6281611737565b610a6c8383611741565b505050565b6000600e54610a7e611567565b600654610a8b9190613dfc565b610a959190613dfc565b905090565b6001600160a01b0381163314610b0a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610889565b610b1482826117ac565b5050565b6000610b2381611737565b610b2b6116e0565b600f54604051479160009182916001600160a01b03169084908381818185875af1925050503d8060008114610b7c576040519150601f19603f3d011682016040523d82523d6000602084013e610b81565b606091505b509150915081610bb357600f5460405163cd797a4160e01b8152610889916001600160a01b0316908390600401613e0f565b505050610bc06001600255565b50565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610bed81611737565b610bf5611813565b600654421115610bc057600654600d541015610c16576006544203600e5550565b50600d54600e805442929092039091019055565b610c32611674565b15610c5057604051631fbde44560e01b815260040160405180910390fd5b6000610c5b81611737565b60008211610cab5760405162461bcd60e51b815260206004820152601f60248201527f4d6178206d696e74206d7573742062652067726561746572207468616e2030006044820152606401610889565b50600c55565b610cb961169a565b6000610cc481611737565b60115460ff1615610d065760405162461bcd60e51b815260206004820152600c60248201526b1a185cc81c99599d5b99195960a21b6044820152606401610889565b6011805460ff19166001179055600080805b601654811015610db85760168181548110610d3557610d35613e3b565b60009182526020808320909101546014546001600160a01b039091168084526015909252604090922054909350610d6c9190613e51565b6001600160a01b038316600090815260156020526040902060010154610d929190613e68565b92508215610da65760008060008086865af1505b80610db081613e7b565b915050610d18565b50505050565b610dc661169a565b610dce6116e0565b4260125411158015610dee575042601354601254610dec9190613dfc565b115b610e305760405162461bcd60e51b8152602060048201526013602482015272199c9959481b5a5b9d081b9bdd081d985b1a59606a1b6044820152606401610889565b336000908152601760205260408120549003610e5f57604051634e4e22b360e01b815260040160405180910390fd5b60005b33600090815260176020526040902054811015610f5457600554601054604051630d4d151360e01b81523360048201819052602482019290925260448101919091526000916001600160a01b031690630d4d1513906064016020604051808303816000875af1158015610ed9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efd9190613dcd565b604080513381526020810183905260008183015290519192507f12cb4648cf3058b17ceeb33e579f8b0bc269fe0843f3900b8e24b6c54871703c919081900360600190a15080610f4c81613e7b565b915050610e62565b503360009081526017602052604081208054600b805490910190558054600a8054909101905555610a446001600255565b610f8d611674565b15610fab57604051631fbde44560e01b815260040160405180910390fd5b6000610fb681611737565b66038d7ea4c6800085116110265760405162461bcd60e51b815260206004820152603160248201527f537461727420707269636520746f6f206c6f773a20636865636b2074686174206044820152707072696365732061726520696e2077656960781b6064820152608401610889565b66038d7ea4c6800084116110955760405162461bcd60e51b815260206004820152603060248201527f5265737420707269636520746f6f206c6f773a20636865636b2074686174207060448201526f72696365732061726520696e2077656960801b6064820152608401610889565b838510156110fb5760405162461bcd60e51b815260206004820152602d60248201527f5374617274207072696365206d757374206e6f74206265206c6f77657220746860448201526c616e207265737420707269636560981b6064820152608401610889565b6000831161115a5760405162461bcd60e51b815260206004820152602660248201527f50726963652064726f7020736c6f74206d75737420626520677265617465722060448201526507468616e20360d41b6064820152608401610889565b600082116111b55760405162461bcd60e51b815260206004820152602260248201527f48616c6620706572696f64206d7573742062652067726561746572207468616e604482015261020360f41b6064820152608401610889565b60078590556008849055600483905560098290556111d282611865565b600380546001600160801b03191660809290921c9190911790556007546111f890611865565b600360106101000a8154816001600160801b03021916908360801c02179055505050505050565b6000611229611674565b61123d57600454600654610a959190613dfc565b600060045461124a6118cc565b6112549190613eaa565b6004546112619190613e68565b905061126d8142613dfc565b91505090565b61127b611674565b1561129957604051631fbde44560e01b815260040160405180910390fd5b60006112a481611737565b6001600160a01b03821661130d5760405162461bcd60e51b815260206004820152602a60248201527f5061737320636f6e7472616374206d757374206e6f7420626520746865207a65604482015269726f206164647265737360b01b6064820152608401610889565b50600580546001600160a01b0319166001600160a01b0392909216919091179055565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a61135a81611737565b611362611906565b5042600d55565b60009182526001602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61139c611674565b156113ba57604051631fbde44560e01b815260040160405180910390fd5b60006113c581611737565b428310156114215760405162461bcd60e51b8152602060048201526024808201527f4e65772073746172742074696d652063616e6e6f7420626520696e20746865206044820152631c185cdd60e21b6064820152608401610889565b61142b8285613e68565b83146114855760405162461bcd60e51b8152602060048201526024808201527f61756374696f6e206d757374206265206c61746572207468616e2066726565206044820152631b5a5b9d60e21b6064820152608401610889565b50600692909255601391909155601255565b6000806114a26118cc565b905060045460045482816114b8576114b8613e94565b0402905060006114c782611865565b6003549091506000906114de90839060801b611943565b905060006114eb82611c0a565b60035490915060009061150890600160801b900460801b83611943565b9050600061151582612f60565b905060085481101561152657506008545b9695505050505050565b611538611674565b1561155657604051631fbde44560e01b815260040160405180910390fd5b600061156181611737565b50601055565b600354600090819061158290600160801b900460801b612fe4565b90506000611599611594600854611865565b612fe4565b6003549091506000906115b89060801b6115b3858561319c565b6131ae565b905060006115c582612f60565b600a9081018190040295945050505050565b600082815260016020819052604090912001546115f381611737565b610a6c83836117ac565b7fdc72ed553f2544c34465af23b847953efeb813428162d767f9ba5f4013be676061162781611737565b8251825180820361166d57602085016020850160005b84811015611669576020818102848101519084015160009182526017909252604090205560010161163d565b5050505b5050505050565b600060065461168560005460ff1690565b61168f5742611693565b600d545b1015905090565b60005460ff1615610a445760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610889565b60028054036117315760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610889565b60028055565b610bc08133613417565b61174b8282611369565b610b145760008281526001602081815260408084206001600160a01b0386168086529252808420805460ff19169093179092559051339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b6117b68282611369565b15610b145760008281526001602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b61181b613470565b6000805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b60008160000361187757506000919050565b816000611883826134b9565b9050607081101561189c578060700382901b91506118af565b60708111156118af576070810382901c91505b613fff0160701b6001600160701b03919091161760801b92915050565b60006118d6611674565b6118e05750600090565b60005460ff166118f75750600e5460065442030390565b50600e54600654600d54030390565b61190e61169a565b6000805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586118483390565b6000617fff60f084811c8216919084901c8116908290036119885780617fff03611977575061ffff60ef1b91506107fe9050565b505050600160ff1b811682186107fe565b80617fff036119cb576dffffffffffffffffffffffffffff60801b8416156119ba575061ffff60ef1b91506107fe9050565b505050808218600160ff1b166107fe565b600160801b600160ff1b038416600003611a1b57600160801b600160ff1b038516600003611a03575061ffff60ef1b91506107fe9050565b505050808218600160ff1b16617fff60f01b176107fe565b6001600160701b03608085901c166000829003611a3b5760019150611a42565b600160701b175b6001600160701b03608087901c166000849003611a85578015611a80576000611a6a826134b9565b6001955060e20393840160711901939190911b90505b611a8f565b600160701b1760721b5b818181611a9e57611a9e613e94565b04905080600003611ace57600160ff1b87871816611abd576000611ac3565b600160ff1b5b9450505050506107fe565b6001606c1b811015611ae257611ae2613ecc565b6000600160731b821015611b2157600160721b821015611b1657600160711b821015611b0f576070611b19565b6071611b19565b60725b60ff16611b2a565b611b2a826134b9565b905083614071018186011115611b4857617fff945060009150611bdb565b83818601613ffc011015611b63576000945060009150611bdb565b83818601613f8c011015611bb0578385613ffc011115611b8e578385613ffc010382901b9150611ba7565b8385613ffc011015611ba757613ffc8585030382901c91505b60009450611bdb565b6070811115611bc3576070810382901c91505b6001600160701b038216915083818601613f8d010394505b81607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b955050505050506107fe565b60006001607f1b608083901c90811190617fff60f085901c8116916001600160701b03169082148015611c3c57508015155b15611c50575061ffff60ef1b949350505050565b61400d821115611c765782611c6a57617fff60f01b611c6d565b60005b95945050505050565b613f7f821015611c8f5750613fff60f01b949350505050565b81600003611ca05760019150611ca7565b600160701b175b613fef821115611cbd57613fee1982011b611ccf565b613fef821015611ccf57613fef8290031c5b828015611ce0575061203760811b81115b15611cf057506000949350505050565b82158015611d0f5750713fffffffffffffffffffffffffffffffffff81115b15611d235750617fff60f01b949350505050565b6001600160801b0381169060801c838015611d3d57508115155b15611d49579019906001015b6001607f1b82811615611d6d5770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b6001607e1b831615611d90577001306fe0a31b7152de8d5a46305c85edec0260801c5b6001607d1b831615611db3577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b6001607c1b831615611dd65770010b5586cf9890f6298b92b71842a983630260801c5b6001607b1b831615611df9577001059b0d31585743ae7c548eb68ca417fd0260801c5b6001607a1b831615611e1c57700102c9a3e778060ee6f7caca4f7a29bde80260801c5b600160791b831615611e3f5770010163da9fb33356d84a66ae336dcdfa3f0260801c5b600160781b831615611e6257700100b1afa5abcbed6129ab13ec11dc95430260801c5b600160771b831615611e855770010058c86da1c09ea1ff19d294cf2f679b0260801c5b600160761b831615611ea8577001002c605e2e8cec506d21bfc89a23a00f0260801c5b600160751b831615611ecb57700100162f3904051fa128bca9c55c31e5df0260801c5b600160741b831615611eee577001000b175effdc76ba38e31671ca9397250260801c5b600160731b831615611f1157700100058ba01fb9f96d6cacd4b180917c3d0260801c5b600160721b831615611f345770010002c5cc37da9491d0985c348c68e7b30260801c5b600160711b831615611f57577001000162e525ee054754457d59952920260260801c5b600160701b831615611f7a5770010000b17255775c040618bf4a4ade83fc0260801c5b6001606f1b831615611f9d577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6001606e1b831615611fc057700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6001606d1b831615611fe35770010000162e43f4f831060e02d839a9d16d0260801c5b6001606c1b83161561200657700100000b1721bcfc99d9f890ea069117630260801c5b6001606b1b8316156120295770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6001606a1b83161561204c577001000002c5c863b73f016468f6bac5ca2b0260801c5b600160691b83161561206f57700100000162e430e5a18f6119e3c02282a50260801c5b600160681b831615612092577001000000b1721835514b86e6d96efd1bfe0260801c5b600160671b8316156120b557700100000058b90c0b48c6be5df846c5b2ef0260801c5b600160661b8316156120d85770010000002c5c8601cc6b9e94213c72737a0260801c5b600160651b8316156120fb577001000000162e42fff037df38aa2b219f060260801c5b600160641b83161561211e5770010000000b17217fba9c739aa5819f44f90260801c5b600160631b831615612141577001000000058b90bfcdee5acd3c1cedc8230260801c5b600160621b83161561216457700100000002c5c85fe31f35a6a30da1be500260801c5b600160611b8316156121875770010000000162e42ff0999ce3541b9fffcf0260801c5b600160601b8316156121aa57700100000000b17217f80f4ef5aadda455540260801c5b6001605f1b8316156121cd5770010000000058b90bfbf8479bd5a81b51ad0260801c5b6001605e1b8316156121f0577001000000002c5c85fdf84bd62ae30a74cc0260801c5b6001605d1b83161561221357700100000000162e42fefb2fed257559bdaa0260801c5b6001605c1b831615612236577001000000000b17217f7d5a7716bba4a9ae0260801c5b6001605b1b83161561225957700100000000058b90bfbe9ddbac5e109cce0260801c5b6001605a1b83161561227c5770010000000002c5c85fdf4b15de6f17eb0d0260801c5b600160591b83161561229f577001000000000162e42fefa494f1478fde050260801c5b600160581b8316156122c25770010000000000b17217f7d20cf927c8e94c0260801c5b600160571b8316156122e5577001000000000058b90bfbe8f71cb4e4b33d0260801c5b600160561b83161561230857700100000000002c5c85fdf477b662b269450260801c5b600160551b83161561232b5770010000000000162e42fefa3ae53369388c0260801c5b600160541b83161561234e57700100000000000b17217f7d1d351a389d400260801c5b600160531b8316156123715770010000000000058b90bfbe8e8b2d3d4ede0260801c5b600160521b831615612394577001000000000002c5c85fdf4741bea6e77e0260801c5b600160511b8316156123b757700100000000000162e42fefa39fe95583c20260801c5b600160501b8316156123da577001000000000000b17217f7d1cfb72b45e10260801c5b698000000000000000000083161561240357700100000000000058b90bfbe8e7cc35c3f00260801c5b694000000000000000000083161561242c5770010000000000002c5c85fdf473e242ea380260801c5b6920000000000000000000831615612455577001000000000000162e42fefa39f02b772c0260801c5b691000000000000000000083161561247e5770010000000000000b17217f7d1cf7d83c1a0260801c5b69080000000000000000008316156124a7577001000000000000058b90bfbe8e7bdcbe2e0260801c5b69040000000000000000008316156124d057700100000000000002c5c85fdf473dea871f0260801c5b69020000000000000000008316156124f95770010000000000000162e42fefa39ef44d910260801c5b690100000000000000000083161561252257700100000000000000b17217f7d1cf79e9490260801c5b6880000000000000000083161561254a5770010000000000000058b90bfbe8e7bce5440260801c5b68400000000000000000831615612572577001000000000000002c5c85fdf473de6eca0260801c5b6820000000000000000083161561259a57700100000000000000162e42fefa39ef366f0260801c5b681000000000000000008316156125c2577001000000000000000b17217f7d1cf79afa0260801c5b680800000000000000008316156125ea57700100000000000000058b90bfbe8e7bcd6d0260801c5b680400000000000000008316156126125770010000000000000002c5c85fdf473de6b20260801c5b6802000000000000000083161561263a577001000000000000000162e42fefa39ef3580260801c5b600160401b83161561265d5770010000000000000000b17217f7d1cf79ab0260801c5b678000000000000000831615612684577001000000000000000058b90bfbe8e7bcd50260801c5b6740000000000000008316156126ab57700100000000000000002c5c85fdf473de6a0260801c5b6720000000000000008316156126d25770010000000000000000162e42fefa39ef340260801c5b6710000000000000008316156126f957700100000000000000000b17217f7d1cf7990260801c5b6708000000000000008316156127205770010000000000000000058b90bfbe8e7bcc0260801c5b670400000000000000831615612747577001000000000000000002c5c85fdf473de50260801c5b67020000000000000083161561276e57700100000000000000000162e42fefa39ef20260801c5b670100000000000000831615612795577001000000000000000000b17217f7d1cf780260801c5b66800000000000008316156127bb57700100000000000000000058b90bfbe8e7bb0260801c5b66400000000000008316156127e15770010000000000000000002c5c85fdf473dd0260801c5b6620000000000000831615612807577001000000000000000000162e42fefa39ee0260801c5b661000000000000083161561282d5770010000000000000000000b17217f7d1cf60260801c5b6608000000000000831615612853577001000000000000000000058b90bfbe8e7a0260801c5b660400000000000083161561287957700100000000000000000002c5c85fdf473c0260801c5b660200000000000083161561289f5770010000000000000000000162e42fefa39d0260801c5b66010000000000008316156128c557700100000000000000000000b17217f7d1ce0260801c5b658000000000008316156128ea5770010000000000000000000058b90bfbe8e60260801c5b6540000000000083161561290f577001000000000000000000002c5c85fdf4720260801c5b6520000000000083161561293457700100000000000000000000162e42fefa380260801c5b65100000000000831615612959577001000000000000000000000b17217f7d1b0260801c5b6508000000000083161561297e57700100000000000000000000058b90bfbe8d0260801c5b650400000000008316156129a35770010000000000000000000002c5c85fdf460260801c5b650200000000008316156129c8577001000000000000000000000162e42fefa20260801c5b650100000000008316156129ed5770010000000000000000000000b17217f7d00260801c5b648000000000831615612a11577001000000000000000000000058b90bfbe70260801c5b644000000000831615612a3557700100000000000000000000002c5c85fdf30260801c5b642000000000831615612a595770010000000000000000000000162e42fef90260801c5b641000000000831615612a7d57700100000000000000000000000b17217f7c0260801c5b640800000000831615612aa15770010000000000000000000000058b90bfbd0260801c5b640400000000831615612ac5577001000000000000000000000002c5c85fde0260801c5b640200000000831615612ae957700100000000000000000000000162e42fee0260801c5b640100000000831615612b0d577001000000000000000000000000b17217f60260801c5b6380000000831615612b3057700100000000000000000000000058b90bfa0260801c5b6340000000831615612b535770010000000000000000000000002c5c85fc0260801c5b6320000000831615612b76577001000000000000000000000000162e42fd0260801c5b6310000000831615612b995770010000000000000000000000000b17217e0260801c5b6308000000831615612bbc577001000000000000000000000000058b90be0260801c5b6304000000831615612bdf57700100000000000000000000000002c5c85e0260801c5b6302000000831615612c025770010000000000000000000000000162e42e0260801c5b6301000000831615612c2557700100000000000000000000000000b172160260801c5b62800000831615612c475770010000000000000000000000000058b90a0260801c5b62400000831615612c69577001000000000000000000000000002c5c840260801c5b62200000831615612c8b57700100000000000000000000000000162e410260801c5b62100000831615612cad577001000000000000000000000000000b17200260801c5b62080000831615612ccf57700100000000000000000000000000058b8f0260801c5b62040000831615612cf15770010000000000000000000000000002c5c70260801c5b62020000831615612d13577001000000000000000000000000000162e30260801c5b62010000831615612d355770010000000000000000000000000000b1710260801c5b618000831615612d56577001000000000000000000000000000058b80260801c5b614000831615612d7757700100000000000000000000000000002c5b0260801c5b612000831615612d985770010000000000000000000000000000162d0260801c5b611000831615612db957700100000000000000000000000000000b160260801c5b610800831615612dda5770010000000000000000000000000000058a0260801c5b610400831615612dfb577001000000000000000000000000000002c40260801c5b610200831615612e1c577001000000000000000000000000000001610260801c5b610100831615612e3d577001000000000000000000000000000000b00260801c5b6080831615612e5d577001000000000000000000000000000000570260801c5b6040831615612e7d5770010000000000000000000000000000002b0260801c5b6020831615612e9d577001000000000000000000000000000000150260801c5b6010831615612ebd5770010000000000000000000000000000000a0260801c5b6008831615612edd577001000000000000000000000000000000040260801c5b6004831615612efd577001000000000000000000000000000000010260801c5b84612f1e57600f81901c6001600160701b03169050613fff82019150612f4d565b613ffe8211612f4357600f81901c6001600160701b0316905081613fff039150612f4d565b600091613fee19011c5b60709190911b1760801b95945050505050565b6000617fff60f083901c16613fff811015612f7e5750600092915050565b6001607f1b608084901c10612f9257600080fd5b6140fe811115612fa157600080fd5b600160701b6001600160701b03608085901c161761406f821015612fcb5761406f8290031c612fdd565b61406f821115612fdd5761406e1982011b5b9392505050565b60006001607f1b608083901c1115613002575061ffff60ef1b919050565b6001600160801b03198216613fff60f01b0361302057506000919050565b617fff60f083901c811690819003613039575090919050565b6001600160701b03608084901c1660008290036130595760019150613060565b600160701b175b8060000361307957506001600160f01b03199392505050565b600061406f81613fff851061309f5750600f9290921b9160009150613ffe1984016130de565b60019250600160701b84106130c15784613ffe039050600f84901b93506130de565b60006130cc856134b9565b607f8190039590951b9461406d039150505b836001607f1b036131145782156130f3576001015b60006130fe826134b9565b60700390508082901b9150808303925050613162565b600083613122576000613125565b60015b60ff1690505b600160701b8210156131605793800260ff81901c607f81019190911c94600019939093019260019290921b908218019061312b565b505b806001600160701b0316607083901b8461317d576000613183565b6001607f1b5b6001600160801b0316171760801b979650505050505050565b6000612fdd83600160ff1b8418613557565b6000617fff60f084811c8216919084901c81169082900361324d5780617fff03613229576001600160801b0319808516908616036131f757505050600160ff1b811682186107fe565b6001600160801b031985851816600160ff1b03613219575050508181176107fe565b5061ffff60ef1b91506107fe9050565b600160801b600160ff1b038416600003611977575061ffff60ef1b91506107fe9050565b80617fff0361328b57600160801b600160ff1b03851660000361327a575061ffff60ef1b91506107fe9050565b505050600160ff1b821681186107fe565b6001600160701b03608086901c1660008390036132ab57600192506132b2565b600160701b175b6001600160701b03608086901c1660008390036132d257600192506132d9565b600160701b175b8082029150816000036132fa57600160ff1b87871816611abd576000611ac3565b928201926000600160e11b83101561332d57600160e01b83101561332657613321836134b9565b613330565b60e0613330565b60e15b9050614070818601101561334b5760009450600092506133e8565b6140e0818601101561338e5761407085101561337057846140700383901c9250613385565b61407085111561338557614070850383901b92505b600094506133e8565b61c0dd81860111156133a857617fff9450600092506133e8565b60708111156133bf576070810383901c92506133d2565b60708110156133d2578060700383901b92505b6001600160701b03831692506140df8186010394505b82607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b955050505050506107fe565b6134218282611369565b610b145761342e81613921565b613439836020613933565b60405160200161344a929190613ee2565b60408051601f198184030181529082905262461bcd60e51b825261088991600401613dba565b60005460ff16610a445760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610889565b60008082116134c757600080fd5b6000600160801b83106134dc57608092831c92015b600160401b83106134ef57604092831c92015b640100000000831061350357602092831c92015b62010000831061351557601092831c92015b610100831061352657600892831c92015b6010831061353657600492831c92015b6004831061354657600292831c92015b600283106107fe5760010192915050565b6000617fff60f084811c8216919084901c8116908290036135a35780617fff03613599576001600160801b0319808516908616036132195784925050506107fe565b84925050506107fe565b80617fff036135b65783925050506107fe565b6001607f1b608086901c90811015906001600160701b031660008490036135e057600193506135e7565b600160701b175b6001607f1b608087901c90811015906001600160701b031660008590036136115760019450613618565b600160701b175b8260000361364b576001600160801b03198816600160ff1b1461363b578761363e565b60005b96505050505050506107fe565b8060000361366e576001600160801b03198916600160ff1b1461363b578861363e565b8486038215158515150361377757607081131561369457899750505050505050506107fe565b60008113156136a65790811c906136d5565b606f198112156136bf57889750505050505050506107fe565b60008112156136d5578060000384901c93508596505b92810192600160711b84106136f0576001968701969390931c925b86617fff03613721578461370957617fff60f01b613713565b6001600160f01b03195b9750505050505050506107fe565b600160701b8410156137365760009650613743565b6001600160701b03841693505b83607088901b8661375557600061375b565b6001607f1b5b6001600160801b0316171760801b9750505050505050506107fe565b600081131561379257600184901b93506001870396506137a9565b60008112156137a957600182901b91506001860396505b60708113156137bb5760019150613808565b60018113156137d8576001810360018303901c6001019150613808565b606f198112156137eb5760019350613808565b600019811215613808576001816000030360018503901c60010193505b818410613819578184039350613822565b83820393508294505b8360000361383b5750600096506107fe95505050505050565b6000613846856134b9565b90508060710361386b57600185901c6001600160701b031694506001880197506138ba565b60708110156138ad5760708190038089111561389a578086901b6001600160701b0316955080890398506138a7565b600098600019019590951b945b506138ba565b6001600160701b03851694505b87617fff036138ec57856138d357617fff60f01b6138dd565b6001600160f01b03195b985050505050505050506107fe565b84607089901b876138fe576000613904565b6001607f1b5b6001600160801b0316171760801b985050505050505050506107fe565b60606107fe6001600160a01b03831660145b60606000613942836002613e51565b61394d906002613dfc565b67ffffffffffffffff81111561396557613965613bd2565b6040519080825280601f01601f19166020018201604052801561398f576020820181803683370190505b509050600360fc1b816000815181106139aa576139aa613e3b565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106139d9576139d9613e3b565b60200101906001600160f81b031916908160001a90535060006139fd846002613e51565b613a08906001613dfc565b90505b6001811115613a80576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613a3c57613a3c613e3b565b1a60f81b828281518110613a5257613a52613e3b565b60200101906001600160f81b031916908160001a90535060049490941c93613a7981613f57565b9050613a0b565b508315612fdd5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610889565b600060208284031215613ae157600080fd5b81356001600160e01b031981168114612fdd57600080fd5b600060208284031215613b0b57600080fd5b5035919050565b6001600160a01b0381168114610bc057600080fd5b60008060408385031215613b3a57600080fd5b823591506020830135613b4c81613b12565b809150509250929050565b60008060008060808587031215613b6d57600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215613b9b57600080fd5b8135612fdd81613b12565b600080600060608486031215613bbb57600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c1157613c11613bd2565b604052919050565b600067ffffffffffffffff821115613c3357613c33613bd2565b5060051b60200190565b600082601f830112613c4e57600080fd5b81356020613c63613c5e83613c19565b613be8565b82815260059290921b84018101918181019086841115613c8257600080fd5b8286015b84811015613c9d5780358352918301918301613c86565b509695505050505050565b60008060408385031215613cbb57600080fd5b823567ffffffffffffffff80821115613cd357600080fd5b818501915085601f830112613ce757600080fd5b81356020613cf7613c5e83613c19565b82815260059290921b84018101918181019089841115613d1657600080fd5b948201945b83861015613d3d578535613d2e81613b12565b82529482019490820190613d1b565b96505086013592505080821115613d5357600080fd5b50613d6085828601613c3d565b9150509250929050565b60005b83811015613d85578181015183820152602001613d6d565b50506000910152565b60008151808452613da6816020860160208601613d6a565b601f01601f19169290920160200192915050565b602081526000612fdd6020830184613d8e565b600060208284031215613ddf57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b808201808211156107fe576107fe613de6565b6001600160a01b0383168152604060208201819052600090613e3390830184613d8e565b949350505050565b634e487b7160e01b600052603260045260246000fd5b80820281158282048414176107fe576107fe613de6565b818103818111156107fe576107fe613de6565b600060018201613e8d57613e8d613de6565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082613ec757634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052600160045260246000fd5b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613f1a816017850160208801613d6a565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613f4b816028840160208801613d6a565b01602801949350505050565b600081613f6657613f66613de6565b50600019019056fea2646970667358221220d3532ca450f4fc1392af2c734e14b40ab7d0fbe2b307af78ee058290054ea20864736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008cdbd7010bd197848e95c1fd7f6e870aac9b0d3c0000000000000000000000000000000000000000000000000000000065392d7000000000000000000000000000000000000000000000000029a2241af62c000000000000000000000000000000000000000000000000000001aa535d3d0c0000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000030700000000000000000000000000000000000000000000000000000000000006a400000000000000000000000000000000000000000000000000000000000000020000000000000000000000006b15fd9cc33dd0852f80567549e552d20a5bdce30000000000000000000000000000000000000000000000000000000065391f600000000000000000000000000000000000000000000000000000000000000e10
-----Decoded View---------------
Arg [0] : passes_ (address): 0x8cDBd7010Bd197848e95C1FD7F6E870AaC9b0d3C
Arg [1] : startTime_ (uint256): 1698246000
Arg [2] : startPrice_ (uint256): 3000000000000000000
Arg [3] : restPrice_ (uint256): 120000000000000000
Arg [4] : priceDropSlot_ (uint256): 10
Arg [5] : halfPeriod_ (uint256): 775
Arg [6] : maxMint_ (uint256): 1700
Arg [7] : projectId_ (uint256): 2
Arg [8] : beneficiary_ (address): 0x6b15FD9CC33dD0852F80567549E552D20a5BDCe3
Arg [9] : freeMintStartTime_ (uint256): 1698242400
Arg [10] : freeMintDuration_ (uint256): 3600
-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 0000000000000000000000008cdbd7010bd197848e95c1fd7f6e870aac9b0d3c
Arg [1] : 0000000000000000000000000000000000000000000000000000000065392d70
Arg [2] : 00000000000000000000000000000000000000000000000029a2241af62c0000
Arg [3] : 00000000000000000000000000000000000000000000000001aa535d3d0c0000
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000307
Arg [6] : 00000000000000000000000000000000000000000000000000000000000006a4
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [8] : 0000000000000000000000006b15fd9cc33dd0852f80567549e552d20a5bdce3
Arg [9] : 0000000000000000000000000000000000000000000000000000000065391f60
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000e10
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.