My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x396794c1f38bb049667d003ef12c098cc981577271716d20d07053904f21020a | 0x60806040 | 8393098 | 19 days 3 hrs ago | 0xf60f3a45c7d4476019262fc1ff6756fc15042f13 | IN | Create: TicksFeesReader | 0 CRO | 9.146874054257 |
[ Download CSV Export ]
Contract Name:
TicksFeesReader
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 100000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity 0.8.9; pragma abicoder v2; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {IPoolStorage} from '../interfaces/pool/IPoolStorage.sol'; import {IBasePositionManager} from '../interfaces/periphery/IBasePositionManager.sol'; import {MathConstants as C} from '../libraries/MathConstants.sol'; import {QtyDeltaMath} from '../libraries/QtyDeltaMath.sol'; import {FullMath} from '../libraries/FullMath.sol'; import {ReinvestmentMath} from '../libraries/ReinvestmentMath.sol'; import {SafeCast} from '../libraries/SafeCast.sol'; import {TickMath as T} from '../libraries/TickMath.sol'; contract TicksFeesReader { using SafeCast for uint256; /// @dev Simplest method that attempts to fetch all initialized ticks /// Has the highest probability of running out of gas function getAllTicks(IPoolStorage pool) external view returns (int24[] memory allTicks) { // + 3 because of MIN_TICK, 0 and MAX_TICK // count (1, MAX_TICK - 1) * 2 uint32 maxNumTicks = uint32((uint256(int256((T.MAX_TICK - 1) / pool.tickDistance()))) * 2 + 3); allTicks = new int24[](maxNumTicks); int24 currentTick = T.MIN_TICK; allTicks[0] = currentTick; uint32 i = 1; while (currentTick < T.MAX_TICK) { (, currentTick) = pool.initializedTicks(currentTick); allTicks[i] = currentTick; i++; } } /// @dev Fetches all initialized ticks with a specified startTick (searches uptick) /// @dev 0 length = Use maximum length function getTicksInRange( IPoolStorage pool, int24 startTick, uint32 length ) external view returns (int24[] memory allTicks) { (int24 previous, int24 next) = pool.initializedTicks(startTick); // startTick is uninitialized, return if (previous == 0 && next == 0) return allTicks; // calculate num ticks from starting tick uint32 maxNumTicks; if (length == 0) { int24 tickDistance = pool.tickDistance(); // tickDistance should always be positive if (startTick == T.MIN_TICK) { maxNumTicks = uint32((uint256(int256((T.MAX_TICK - 1) / tickDistance))) * 2 + 3); } else if (startTick == T.MAX_TICK) { maxNumTicks = 1; } else { // startTick % tickDistance == 0 maxNumTicks = uint32(uint256(int256((T.MAX_TICK - 1 - startTick) / tickDistance))) + 2; } } else { maxNumTicks = length; } allTicks = new int24[](maxNumTicks); for (uint32 i = 0; i < maxNumTicks; i++) { allTicks[i] = startTick; if (startTick == T.MAX_TICK) break; (, startTick) = pool.initializedTicks(startTick); } } function getNearestInitializedTicks(IPoolStorage pool, int24 tick) external view returns (int24 previous, int24 next) { require(T.MIN_TICK <= tick && tick <= T.MAX_TICK, 'tick not in range'); // if queried tick already initialized, fetch and return values (previous, next) = pool.initializedTicks(tick); if (previous != 0 || next != 0) return (previous, next); // search downtick from MAX_TICK if (tick > 0) { previous = T.MAX_TICK; while (previous > tick) { (previous, ) = pool.initializedTicks(previous); } (, next) = pool.initializedTicks(previous); } else { // search uptick from MIN_TICK next = T.MIN_TICK; while (next < tick) { (, next) = pool.initializedTicks(next); } (previous, ) = pool.initializedTicks(next); } } function getTotalRTokensOwedToPosition( IBasePositionManager posManager, IPoolStorage pool, uint256 tokenId ) public view returns (uint256 rTokenOwed) { (IBasePositionManager.Position memory pos, ) = posManager.positions(tokenId); require( posManager.addressToPoolId(address(pool)) == pos.poolId, 'tokenId and pool dont match' ); // sync pool fee growth (uint256 feeGrowthGlobal, ) = _syncFeeGrowthGlobal(pool); // calc feeGrowthInside uint256 feeGrowthInside = _calcFeeGrowthInside(pool, pos, feeGrowthGlobal); // take difference in feeGrowthInside against position feeGrowthInside if (feeGrowthInside != pos.feeGrowthInsideLast) { uint256 feeGrowthInsideDiff; unchecked { feeGrowthInsideDiff = feeGrowthInside - pos.feeGrowthInsideLast; } pos.rTokenOwed += FullMath.mulDivFloor(pos.liquidity, feeGrowthInsideDiff, C.TWO_POW_96); } rTokenOwed = pos.rTokenOwed; } function getTotalFeesOwedToPosition( IBasePositionManager posManager, IPoolStorage pool, uint256 tokenId ) external view returns (uint256 token0Owed, uint256 token1Owed) { (IBasePositionManager.Position memory pos, ) = posManager.positions(tokenId); require( posManager.addressToPoolId(address(pool)) == pos.poolId, 'tokenId and pool dont match' ); // sync pool fee growth and rTotalSupply (uint256 feeGrowthGlobal, uint256 rTotalSupply) = _syncFeeGrowthGlobal(pool); // calc feeGrowthInside uint256 feeGrowthInside = _calcFeeGrowthInside(pool, pos, feeGrowthGlobal); // take difference in feeGrowthInside against position feeGrowthInside if (feeGrowthInside != pos.feeGrowthInsideLast) { uint256 feeGrowthInsideDiff; unchecked { feeGrowthInsideDiff = feeGrowthInside - pos.feeGrowthInsideLast; } pos.rTokenOwed += FullMath.mulDivFloor(pos.liquidity, feeGrowthInsideDiff, C.TWO_POW_96); } (, uint128 reinvestL, ) = pool.getLiquidityState(); uint256 deltaL = FullMath.mulDivFloor(pos.rTokenOwed, reinvestL, rTotalSupply); (uint160 sqrtP, , , ) = pool.getPoolState(); // finally, calculate token amounts owed token0Owed = QtyDeltaMath.getQty0FromBurnRTokens(sqrtP, deltaL); token1Owed = QtyDeltaMath.getQty1FromBurnRTokens(sqrtP, deltaL); } function _syncFeeGrowthGlobal(IPoolStorage pool) internal view returns (uint256 feeGrowthGlobal, uint256 rTotalSupply) { (uint128 baseL, uint128 reinvestL, uint128 reinvestLLast) = pool.getLiquidityState(); feeGrowthGlobal = pool.getFeeGrowthGlobal(); rTotalSupply = IERC20(address(pool)).totalSupply(); // logic ported from Pool._syncFeeGrowth() uint256 rMintQty = ReinvestmentMath.calcrMintQty( uint256(reinvestL), uint256(reinvestLLast), baseL, rTotalSupply ); if (rMintQty != 0) { // add rMintQty to rTotalSupply before deductGovermentFee rTotalSupply += rMintQty; rMintQty = _deductGovermentFee(pool, rMintQty); unchecked { feeGrowthGlobal += FullMath.mulDivFloor(rMintQty, C.TWO_POW_96, baseL); } } } /// @return the lp fee without governance fee function _deductGovermentFee(IPoolStorage pool, uint256 rMintQty) internal view returns (uint256) { // fetch governmentFeeUnits (, uint24 governmentFeeUnits) = pool.factory().feeConfiguration(); if (governmentFeeUnits == 0) { return rMintQty; } // unchecked due to governmentFeeUnits <= 20000 unchecked { uint256 rGovtQty = (rMintQty * governmentFeeUnits) / C.FEE_UNITS; return rMintQty - rGovtQty; } } function _calcFeeGrowthInside( IPoolStorage pool, IBasePositionManager.Position memory pos, uint256 feeGrowthGlobal ) internal view returns (uint256 feeGrowthInside) { (, , uint256 feeGrowthOutsideLowerTick, ) = pool.ticks(pos.tickLower); (, , uint256 feeGrowthOutsideUpperTick, ) = pool.ticks(pos.tickUpper); (, int24 currentTick, , ) = pool.getPoolState(); unchecked { if (currentTick < pos.tickLower) { feeGrowthInside = feeGrowthOutsideLowerTick - feeGrowthOutsideUpperTick; } else if (currentTick >= pos.tickUpper) { feeGrowthInside = feeGrowthOutsideUpperTick - feeGrowthOutsideLowerTick; } else { feeGrowthInside = feeGrowthGlobal - feeGrowthOutsideLowerTick - feeGrowthOutsideUpperTick; } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import {IFactory} from '../IFactory.sol'; import {IPoolOracle} from '../oracle/IPoolOracle.sol'; interface IPoolStorage { /// @notice The contract that deployed the pool, which must adhere to the IFactory interface /// @return The contract address function factory() external view returns (IFactory); /// @notice The oracle contract that stores necessary data for price oracle /// @return The contract address function poolOracle() external view returns (IPoolOracle); /// @notice The first of the two tokens of the pool, sorted by address /// @return The token contract address function token0() external view returns (IERC20); /// @notice The second of the two tokens of the pool, sorted by address /// @return The token contract address function token1() external view returns (IERC20); /// @notice The fee to be charged for a swap in basis points /// @return The swap fee in basis points function swapFeeUnits() external view returns (uint24); /// @notice The pool tick distance /// @dev Ticks can only be initialized and used at multiples of this value /// It remains an int24 to avoid casting even though it is >= 1. /// e.g: a tickDistance of 5 means ticks can be initialized every 5th tick, i.e., ..., -10, -5, 0, 5, 10, ... /// @return The tick distance function tickDistance() external view returns (int24); /// @notice Maximum gross liquidity that an initialized tick can have /// @dev This is to prevent overflow the pool's active base liquidity (uint128) /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool /// @return The max amount of liquidity per tick function maxTickLiquidity() external view returns (uint128); /// @notice Look up information about a specific tick in the pool /// @param tick The tick to look up /// @return liquidityGross total liquidity amount from positions that uses this tick as a lower or upper tick /// liquidityNet how much liquidity changes when the pool tick crosses above the tick /// feeGrowthOutside the fee growth on the other side of the tick relative to the current tick /// secondsPerLiquidityOutside the seconds per unit of liquidity spent on the other side of the tick relative to the current tick function ticks(int24 tick) external view returns ( uint128 liquidityGross, int128 liquidityNet, uint256 feeGrowthOutside, uint128 secondsPerLiquidityOutside ); /// @notice Returns the previous and next initialized ticks of a specific tick /// @dev If specified tick is uninitialized, the returned values are zero. /// @param tick The tick to look up function initializedTicks(int24 tick) external view returns (int24 previous, int24 next); /// @notice Returns the information about a position by the position's key /// @return liquidity the liquidity quantity of the position /// @return feeGrowthInsideLast fee growth inside the tick range as of the last mint / burn action performed function getPositions( address owner, int24 tickLower, int24 tickUpper ) external view returns (uint128 liquidity, uint256 feeGrowthInsideLast); /// @notice Fetches the pool's prices, ticks and lock status /// @return sqrtP sqrt of current price: sqrt(token1/token0) /// @return currentTick pool's current tick /// @return nearestCurrentTick pool's nearest initialized tick that is <= currentTick /// @return locked true if pool is locked, false otherwise function getPoolState() external view returns ( uint160 sqrtP, int24 currentTick, int24 nearestCurrentTick, bool locked ); /// @notice Fetches the pool's liquidity values /// @return baseL pool's base liquidity without reinvest liqudity /// @return reinvestL the liquidity is reinvested into the pool /// @return reinvestLLast last cached value of reinvestL, used for calculating reinvestment token qty function getLiquidityState() external view returns ( uint128 baseL, uint128 reinvestL, uint128 reinvestLLast ); /// @return feeGrowthGlobal All-time fee growth per unit of liquidity of the pool function getFeeGrowthGlobal() external view returns (uint256); /// @return secondsPerLiquidityGlobal All-time seconds per unit of liquidity of the pool /// @return lastUpdateTime The timestamp in which secondsPerLiquidityGlobal was last updated function getSecondsPerLiquidityData() external view returns (uint128 secondsPerLiquidityGlobal, uint32 lastUpdateTime); /// @notice Calculates and returns the active time per unit of liquidity until current block.timestamp /// @param tickLower The lower tick (of a position) /// @param tickUpper The upper tick (of a position) /// @return secondsPerLiquidityInside active time (multiplied by 2^96) /// between the 2 ticks, per unit of liquidity. function getSecondsPerLiquidityInside(int24 tickLower, int24 tickUpper) external view returns (uint128 secondsPerLiquidityInside); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; import {IERC721Metadata} from '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol'; import {IRouterTokenHelper} from './IRouterTokenHelper.sol'; import {IBasePositionManagerEvents} from './base_position_manager/IBasePositionManagerEvents.sol'; import {IERC721Permit} from './IERC721Permit.sol'; interface IBasePositionManager is IRouterTokenHelper, IBasePositionManagerEvents { struct Position { // the nonce for permits uint96 nonce; // the address that is approved for spending this token address operator; // the ID of the pool with which this token is connected uint80 poolId; // the tick range of the position int24 tickLower; int24 tickUpper; // the liquidity of the position uint128 liquidity; // the current rToken that the position owed uint256 rTokenOwed; // fee growth per unit of liquidity as of the last update to liquidity uint256 feeGrowthInsideLast; } struct PoolInfo { address token0; uint24 fee; address token1; } /// @notice Params for the first time adding liquidity, mint new nft to sender /// @param token0 the token0 of the pool /// @param token1 the token1 of the pool /// - must make sure that token0 < token1 /// @param fee the pool's fee in fee units /// @param tickLower the position's lower tick /// @param tickUpper the position's upper tick /// - must make sure tickLower < tickUpper, and both are in tick distance /// @param ticksPrevious the nearest tick that has been initialized and lower than or equal to /// the tickLower and tickUpper, use to help insert the tickLower and tickUpper if haven't initialized /// @param amount0Desired the desired amount for token0 /// @param amount1Desired the desired amount for token1 /// @param amount0Min min amount of token 0 to add /// @param amount1Min min amount of token 1 to add /// @param recipient the owner of the position /// @param deadline time that the transaction will be expired struct MintParams { address token0; address token1; uint24 fee; int24 tickLower; int24 tickUpper; int24[2] ticksPrevious; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; } /// @notice Params for adding liquidity to the existing position /// @param tokenId id of the position to increase its liquidity /// @param ticksPrevious the nearest tick that has been initialized and lower than or equal to /// the tickLower and tickUpper, use to help insert the tickLower and tickUpper if haven't initialized /// only needed if the position has been closed and the owner wants to add more liquidity /// @param amount0Desired the desired amount for token0 /// @param amount1Desired the desired amount for token1 /// @param amount0Min min amount of token 0 to add /// @param amount1Min min amount of token 1 to add /// @param deadline time that the transaction will be expired struct IncreaseLiquidityParams { uint256 tokenId; int24[2] ticksPrevious; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /// @notice Params for remove liquidity from the existing position /// @param tokenId id of the position to remove its liquidity /// @param amount0Min min amount of token 0 to receive /// @param amount1Min min amount of token 1 to receive /// @param deadline time that the transaction will be expired struct RemoveLiquidityParams { uint256 tokenId; uint128 liquidity; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /// @notice Burn the rTokens to get back token0 + token1 as fees /// @param tokenId id of the position to burn r token /// @param amount0Min min amount of token 0 to receive /// @param amount1Min min amount of token 1 to receive /// @param deadline time that the transaction will be expired struct BurnRTokenParams { uint256 tokenId; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } /// @notice Creates a new pool if it does not exist, then unlocks if it has not been unlocked /// @param token0 the token0 of the pool /// @param token1 the token1 of the pool /// @param fee the fee for the pool /// @param currentSqrtP the initial price of the pool /// @return pool returns the pool address function createAndUnlockPoolIfNecessary( address token0, address token1, uint24 fee, uint160 currentSqrtP ) external payable returns (address pool); function mint(MintParams calldata params) external payable returns ( uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1 ); function addLiquidity(IncreaseLiquidityParams calldata params) external payable returns ( uint128 liquidity, uint256 amount0, uint256 amount1, uint256 additionalRTokenOwed ); function removeLiquidity(RemoveLiquidityParams calldata params) external returns ( uint256 amount0, uint256 amount1, uint256 additionalRTokenOwed ); function burnRTokens(BurnRTokenParams calldata params) external returns ( uint256 rTokenQty, uint256 amount0, uint256 amount1 ); /** * @dev Burn the token by its owner * @notice All liquidity should be removed before burning */ function burn(uint256 tokenId) external payable; function syncFeeGrowth(uint256 tokenId) external returns (uint256 additionalRTokenOwed); function positions(uint256 tokenId) external view returns (Position memory pos, PoolInfo memory info); function addressToPoolId(address pool) external view returns (uint80); function isRToken(address token) external view returns (bool); function nextPoolId() external view returns (uint80); function nextTokenId() external view returns (uint256); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @title Contains constants needed for math libraries library MathConstants { uint256 internal constant TWO_FEE_UNITS = 200_000; uint256 internal constant TWO_POW_96 = 2 ** 96; uint128 internal constant MIN_LIQUIDITY = 100; uint8 internal constant RES_96 = 96; uint24 internal constant FEE_UNITS = 100000; // it is strictly less than 5% price movement if jumping MAX_TICK_DISTANCE ticks int24 internal constant MAX_TICK_DISTANCE = 480; // max number of tick travel when inserting if data changes uint256 internal constant MAX_TICK_TRAVEL = 10; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import {MathConstants as C} from './MathConstants.sol'; import {TickMath} from './TickMath.sol'; import {FullMath} from './FullMath.sol'; import {SafeCast} from './SafeCast.sol'; /// @title Contains helper functions for calculating /// token0 and token1 quantites from differences in prices /// or from burning reinvestment tokens library QtyDeltaMath { using SafeCast for uint256; using SafeCast for int128; function calcUnlockQtys(uint160 initialSqrtP) internal pure returns (uint256 qty0, uint256 qty1) { qty0 = FullMath.mulDivCeiling(C.MIN_LIQUIDITY, C.TWO_POW_96, initialSqrtP); qty1 = FullMath.mulDivCeiling(C.MIN_LIQUIDITY, initialSqrtP, C.TWO_POW_96); } /// @notice Gets the qty0 delta between two prices /// @dev Calculates liquidity / sqrt(lower) - liquidity / sqrt(upper), /// i.e. liquidity * (sqrt(upper) - sqrt(lower)) / (sqrt(upper) * sqrt(lower)) /// rounds up if adding liquidity, rounds down if removing liquidity /// @param lowerSqrtP The lower sqrt price. /// @param upperSqrtP The upper sqrt price. Should be >= lowerSqrtP /// @param liquidity Liquidity quantity /// @param isAddLiquidity true = add liquidity, false = remove liquidity /// @return token0 qty required for position with liquidity between the 2 sqrt prices function calcRequiredQty0( uint160 lowerSqrtP, uint160 upperSqrtP, uint128 liquidity, bool isAddLiquidity ) internal pure returns (int256) { uint256 numerator1 = uint256(liquidity) << C.RES_96; uint256 numerator2; unchecked { numerator2 = upperSqrtP - lowerSqrtP; } return isAddLiquidity ? (divCeiling(FullMath.mulDivCeiling(numerator1, numerator2, upperSqrtP), lowerSqrtP)) .toInt256() : (FullMath.mulDivFloor(numerator1, numerator2, upperSqrtP) / lowerSqrtP).revToInt256(); } /// @notice Gets the token1 delta quantity between two prices /// @dev Calculates liquidity * (sqrt(upper) - sqrt(lower)) /// rounds up if adding liquidity, rounds down if removing liquidity /// @param lowerSqrtP The lower sqrt price. /// @param upperSqrtP The upper sqrt price. Should be >= lowerSqrtP /// @param liquidity Liquidity quantity /// @param isAddLiquidity true = add liquidity, false = remove liquidity /// @return token1 qty required for position with liquidity between the 2 sqrt prices function calcRequiredQty1( uint160 lowerSqrtP, uint160 upperSqrtP, uint128 liquidity, bool isAddLiquidity ) internal pure returns (int256) { unchecked { return isAddLiquidity ? (FullMath.mulDivCeiling(liquidity, upperSqrtP - lowerSqrtP, C.TWO_POW_96)).toInt256() : (FullMath.mulDivFloor(liquidity, upperSqrtP - lowerSqrtP, C.TWO_POW_96)).revToInt256(); } } /// @notice Calculates the token0 quantity proportion to be sent to the user /// for burning reinvestment tokens /// @param sqrtP Current pool sqrt price /// @param liquidity Difference in reinvestment liquidity due to reinvestment token burn /// @return token0 quantity to be sent to the user function getQty0FromBurnRTokens(uint160 sqrtP, uint256 liquidity) internal pure returns (uint256) { return FullMath.mulDivFloor(liquidity, C.TWO_POW_96, sqrtP); } /// @notice Calculates the token1 quantity proportion to be sent to the user /// for burning reinvestment tokens /// @param sqrtP Current pool sqrt price /// @param liquidity Difference in reinvestment liquidity due to reinvestment token burn /// @return token1 quantity to be sent to the user function getQty1FromBurnRTokens(uint160 sqrtP, uint256 liquidity) internal pure returns (uint256) { return FullMath.mulDivFloor(liquidity, sqrtP, C.TWO_POW_96); } /// @notice Returns ceil(x / y) /// @dev division by 0 has unspecified behavior, and must be checked externally /// @param x The dividend /// @param y The divisor /// @return z The quotient, ceil(x / y) function divCeiling(uint256 x, uint256 y) internal pure returns (uint256 z) { // return x / y + ((x % y == 0) ? 0 : 1); require(y > 0); assembly { z := add(div(x, y), gt(mod(x, y), 0)) } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits /// @dev Code has been modified to be compatible with sol 0.8 library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv function mulDivFloor( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then 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(a, b, not(0)) prod0 := mul(a, b) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { require(denominator > 0, '0 denom'); assembly { result := div(prod0, denominator) } return result; } // Make sure the result is less than 2**256. // Also prevents denominator == 0 require(denominator > prod1, 'denom <= prod1'); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0] // Compute remainder using mulmod uint256 remainder; assembly { remainder := mulmod(a, b, denominator) } // Subtract 256 bit number from 512 bit number assembly { prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. uint256 twos = denominator & (~denominator + 1); // Divide denominator by power of two assembly { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly { twos := add(div(sub(0, twos), twos), 1) } unchecked { 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 // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use 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. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // 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 precoditions 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 * inv; } return result; } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivCeiling( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { result = mulDivFloor(a, b, denominator); if (mulmod(a, b, denominator) > 0) { result++; } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import {MathConstants as C} from './MathConstants.sol'; import {FullMath} from './FullMath.sol'; /// @title Contains helper function to calculate the number of reinvestment tokens to be minted library ReinvestmentMath { /// @dev calculate the mint amount with given reinvestL, reinvestLLast, baseL and rTotalSupply /// contribution of lp to the increment is calculated by the proportion of baseL with reinvestL + baseL /// then rMintQty is calculated by mutiplying this with the liquidity per reinvestment token /// rMintQty = rTotalSupply * (reinvestL - reinvestLLast) / reinvestLLast * baseL / (baseL + reinvestL) function calcrMintQty( uint256 reinvestL, uint256 reinvestLLast, uint128 baseL, uint256 rTotalSupply ) internal pure returns (uint256 rMintQty) { uint256 lpContribution = FullMath.mulDivFloor( baseL, reinvestL - reinvestLLast, baseL + reinvestL ); rMintQty = FullMath.mulDivFloor(rTotalSupply, lpContribution, reinvestLLast); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; /// @title Safe casting methods /// @notice Contains methods for safely casting between types library SafeCast { /// @notice Cast a uint256 to uint32, revert on overflow /// @param y The uint256 to be downcasted /// @return z The downcasted integer, now type uint32 function toUint32(uint256 y) internal pure returns (uint32 z) { require((z = uint32(y)) == y); } /// @notice Cast a uint128 to a int128, revert on overflow /// @param y The uint256 to be casted /// @return z The casted integer, now type int256 function toInt128(uint128 y) internal pure returns (int128 z) { require(y < 2**127); z = int128(y); } /// @notice Cast a uint256 to a uint128, revert on overflow /// @param y the uint256 to be downcasted /// @return z The downcasted integer, now type uint128 function toUint128(uint256 y) internal pure returns (uint128 z) { require((z = uint128(y)) == y); } /// @notice Cast a int128 to a uint128 and reverses the sign. /// @param y The int128 to be casted /// @return z = -y, now type uint128 function revToUint128(int128 y) internal pure returns (uint128 z) { unchecked { return type(uint128).max - uint128(y) + 1; } } /// @notice Cast a uint256 to a uint160, revert on overflow /// @param y The uint256 to be downcasted /// @return z The downcasted integer, now type uint160 function toUint160(uint256 y) internal pure returns (uint160 z) { require((z = uint160(y)) == y); } /// @notice Cast a uint256 to a int256, revert on overflow /// @param y The uint256 to be casted /// @return z The casted integer, now type int256 function toInt256(uint256 y) internal pure returns (int256 z) { require(y < 2**255); z = int256(y); } /// @notice Cast a uint256 to a int256 and reverses the sign, revert on overflow /// @param y The uint256 to be casted /// @return z = -y, now type int256 function revToInt256(uint256 y) internal pure returns (int256 z) { require(y < 2**255); z = -int256(y); } /// @notice Cast a int256 to a uint256 and reverses the sign. /// @param y The int256 to be casted /// @return z = -y, now type uint256 function revToUint256(int256 y) internal pure returns (uint256 z) { unchecked { return type(uint256).max - uint256(y) + 1; } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; /// @title Math library for computing sqrt prices from ticks and vice versa /// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports /// prices between 2**-128 and 2**128 library TickMath { /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128 int24 internal constant MIN_TICK = -887272; /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128 int24 internal constant MAX_TICK = -MIN_TICK; /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK) uint160 internal constant MIN_SQRT_RATIO = 4295128739; /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK) uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; /// @notice Calculates sqrt(1.0001^tick) * 2^96 /// @dev Throws if |tick| > max tick /// @param tick The input tick for the above formula /// @return sqrtP A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0) /// at the given tick function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtP) { unchecked { uint256 absTick = uint256(tick < 0 ? -int256(tick) : int256(tick)); require(absTick <= uint256(int256(MAX_TICK)), 'T'); // do bitwise comparison, if i-th bit is turned on, // multiply ratio by hardcoded values of sqrt(1.0001^-(2^i)) * 2^128 // where 0 <= i <= 19 uint256 ratio = (absTick & 0x1 != 0) ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000; if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128; if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128; if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128; if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128; if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128; if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128; if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128; if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128; if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128; if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128; if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; // take reciprocal for positive tick values if (tick > 0) ratio = type(uint256).max / ratio; // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96. // we then downcast because we know the result always fits within 160 bits due to our tick input constraint // we round up in the division so getTickAtSqrtRatio of the output price is always consistent sqrtP = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); } } /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio /// @dev Throws in case sqrtP < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may /// ever return. /// @param sqrtP The sqrt ratio for which to compute the tick as a Q64.96 /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio function getTickAtSqrtRatio(uint160 sqrtP) internal pure returns (int24 tick) { // second inequality must be < because the price can never reach the price at the max tick require(sqrtP >= MIN_SQRT_RATIO && sqrtP < MAX_SQRT_RATIO, 'R'); uint256 ratio = uint256(sqrtP) << 32; uint256 r = ratio; uint256 msb = 0; unchecked { assembly { let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(5, gt(r, 0xFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(4, gt(r, 0xFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(3, gt(r, 0xFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(2, gt(r, 0xF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(1, gt(r, 0x3)) msb := or(msb, f) r := shr(f, r) } assembly { let f := gt(r, 0x1) msb := or(msb, f) } if (msb >= 128) r = ratio >> (msb - 127); else r = ratio << (127 - msb); int256 log_2 = (int256(msb) - 128) << 64; assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(63, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(62, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(61, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(60, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(59, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(58, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(57, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(56, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(55, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(54, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(53, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(52, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(51, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(50, f)) } int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtP ? tickHi : tickLow; } } function getMaxNumberTicks(int24 _tickDistance) internal pure returns (uint24 numTicks) { return uint24(TickMath.MAX_TICK / _tickDistance) * 2; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @title KyberSwap v2 factory /// @notice Deploys KyberSwap v2 pools and manages control over government fees interface IFactory { /// @notice Emitted when a pool is created /// @param token0 First pool token by address sort order /// @param token1 Second pool token by address sort order /// @param swapFeeUnits Fee to be collected upon every swap in the pool, in fee units /// @param tickDistance Minimum number of ticks between initialized ticks /// @param pool The address of the created pool event PoolCreated( address indexed token0, address indexed token1, uint24 indexed swapFeeUnits, int24 tickDistance, address pool ); /// @notice Emitted when a new fee is enabled for pool creation via the factory /// @param swapFeeUnits Fee to be collected upon every swap in the pool, in fee units /// @param tickDistance Minimum number of ticks between initialized ticks for pools created with the given fee event SwapFeeEnabled(uint24 indexed swapFeeUnits, int24 indexed tickDistance); /// @notice Emitted when vesting period changes /// @param vestingPeriod The maximum time duration for which LP fees /// are proportionally burnt upon LP removals event VestingPeriodUpdated(uint32 vestingPeriod); /// @notice Emitted when configMaster changes /// @param oldConfigMaster configMaster before the update /// @param newConfigMaster configMaster after the update event ConfigMasterUpdated(address oldConfigMaster, address newConfigMaster); /// @notice Emitted when fee configuration changes /// @param feeTo Recipient of government fees /// @param governmentFeeUnits Fee amount, in fee units, /// to be collected out of the fee charged for a pool swap event FeeConfigurationUpdated(address feeTo, uint24 governmentFeeUnits); /// @notice Emitted when whitelist feature is enabled event WhitelistEnabled(); /// @notice Emitted when whitelist feature is disabled event WhitelistDisabled(); /// @notice Returns the maximum time duration for which LP fees /// are proportionally burnt upon LP removals function vestingPeriod() external view returns (uint32); /// @notice Returns the tick distance for a specified fee. /// @dev Once added, cannot be updated or removed. /// @param swapFeeUnits Swap fee, in fee units. /// @return The tick distance. Returns 0 if fee has not been added. function feeAmountTickDistance(uint24 swapFeeUnits) external view returns (int24); /// @notice Returns the address which can update the fee configuration function configMaster() external view returns (address); /// @notice Returns the keccak256 hash of the Pool creation code /// This is used for pre-computation of pool addresses function poolInitHash() external view returns (bytes32); /// @notice Returns the pool oracle contract for twap function poolOracle() external view returns (address); /// @notice Fetches the recipient of government fees /// and current government fee charged in fee units function feeConfiguration() external view returns (address _feeTo, uint24 _governmentFeeUnits); /// @notice Returns the status of whitelisting feature of NFT managers /// If true, anyone can mint liquidity tokens /// Otherwise, only whitelisted NFT manager(s) are allowed to mint liquidity tokens function whitelistDisabled() external view returns (bool); //// @notice Returns all whitelisted NFT managers /// If the whitelisting feature is turned on, /// only whitelisted NFT manager(s) are allowed to mint liquidity tokens function getWhitelistedNFTManagers() external view returns (address[] memory); /// @notice Checks if sender is a whitelisted NFT manager /// If the whitelisting feature is turned on, /// only whitelisted NFT manager(s) are allowed to mint liquidity tokens /// @param sender address to be checked /// @return true if sender is a whistelisted NFT manager, false otherwise function isWhitelistedNFTManager(address sender) external view returns (bool); /// @notice Returns the pool address for a given pair of tokens and a swap fee /// @dev Token order does not matter /// @param tokenA Contract address of either token0 or token1 /// @param tokenB Contract address of the other token /// @param swapFeeUnits Fee to be collected upon every swap in the pool, in fee units /// @return pool The pool address. Returns null address if it does not exist function getPool( address tokenA, address tokenB, uint24 swapFeeUnits ) external view returns (address pool); /// @notice Fetch parameters to be used for pool creation /// @dev Called by the pool constructor to fetch the parameters of the pool /// @return factory The factory address /// @return poolOracle The pool oracle for twap /// @return token0 First pool token by address sort order /// @return token1 Second pool token by address sort order /// @return swapFeeUnits Fee to be collected upon every swap in the pool, in fee units /// @return tickDistance Minimum number of ticks between initialized ticks function parameters() external view returns ( address factory, address poolOracle, address token0, address token1, uint24 swapFeeUnits, int24 tickDistance ); /// @notice Creates a pool for the given two tokens and fee /// @param tokenA One of the two tokens in the desired pool /// @param tokenB The other of the two tokens in the desired pool /// @param swapFeeUnits Desired swap fee for the pool, in fee units /// @dev Token order does not matter. tickDistance is determined from the fee. /// Call will revert under any of these conditions: /// 1) pool already exists /// 2) invalid swap fee /// 3) invalid token arguments /// @return pool The address of the newly created pool function createPool( address tokenA, address tokenB, uint24 swapFeeUnits ) external returns (address pool); /// @notice Enables a fee amount with the given tickDistance /// @dev Fee amounts may never be removed once enabled /// @param swapFeeUnits The fee amount to enable, in fee units /// @param tickDistance The distance between ticks to be enforced for all pools created with the given fee amount function enableSwapFee(uint24 swapFeeUnits, int24 tickDistance) external; /// @notice Updates the address which can update the fee configuration /// @dev Must be called by the current configMaster function updateConfigMaster(address) external; /// @notice Updates the vesting period /// @dev Must be called by the current configMaster function updateVestingPeriod(uint32) external; /// @notice Updates the address receiving government fees and fee quantity /// @dev Only configMaster is able to perform the update /// @param feeTo Address to receive government fees collected from pools /// @param governmentFeeUnits Fee amount, in fee units, /// to be collected out of the fee charged for a pool swap function updateFeeConfiguration(address feeTo, uint24 governmentFeeUnits) external; /// @notice Enables the whitelisting feature /// @dev Only configMaster is able to perform the update function enableWhitelist() external; /// @notice Disables the whitelisting feature /// @dev Only configMaster is able to perform the update function disableWhitelist() external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IPoolOracle { /// @notice Owner withdrew funds in the pool oracle in case some funds are stuck there event OwnerWithdrew( address indexed owner, address indexed token, uint256 indexed amount ); /// @notice Emitted by the Pool Oracle for increases to the number of observations that can be stored /// @dev observationCardinalityNext is not the observation cardinality until an observation is written at the index /// just before a mint/swap/burn. /// @param pool The pool address to update /// @param observationCardinalityNextOld The previous value of the next observation cardinality /// @param observationCardinalityNextNew The updated value of the next observation cardinality event IncreaseObservationCardinalityNext( address pool, uint16 observationCardinalityNextOld, uint16 observationCardinalityNextNew ); /// @notice Initalize observation data for the caller. function initializeOracle(uint32 time) external returns (uint16 cardinality, uint16 cardinalityNext); /// @notice Write a new oracle entry into the array /// and update the observation index and cardinality /// Read the Oralce.write function for more details function writeNewEntry( uint16 index, uint32 blockTimestamp, int24 tick, uint128 liquidity, uint16 cardinality, uint16 cardinalityNext ) external returns (uint16 indexUpdated, uint16 cardinalityUpdated); /// @notice Write a new oracle entry into the array, take the latest observaion data as inputs /// and update the observation index and cardinality /// Read the Oralce.write function for more details function write( uint32 blockTimestamp, int24 tick, uint128 liquidity ) external returns (uint16 indexUpdated, uint16 cardinalityUpdated); /// @notice Increase the maximum number of price observations that this pool will store /// @dev This method is no-op if the pool already has an observationCardinalityNext greater than or equal to /// the input observationCardinalityNext. /// @param pool The pool address to be updated /// @param observationCardinalityNext The desired minimum number of observations for the pool to store function increaseObservationCardinalityNext( address pool, uint16 observationCardinalityNext ) external; /// @notice Returns the accumulator values as of each time seconds ago from the latest block time in the array of `secondsAgos` /// @dev Reverts if `secondsAgos` > oldest observation /// @dev It fetches the latest current tick data from the pool /// Read the Oracle.observe function for more details function observeFromPool( address pool, uint32[] memory secondsAgos ) external view returns (int56[] memory tickCumulatives); /// @notice Returns the accumulator values as the time seconds ago from the latest block time of secondsAgo /// @dev Reverts if `secondsAgo` > oldest observation /// @dev It fetches the latest current tick data from the pool /// Read the Oracle.observeSingle function for more details function observeSingleFromPool( address pool, uint32 secondsAgo ) external view returns (int56 tickCumulative); /// @notice Return the latest pool observation data given the pool address function getPoolObservation(address pool) external view returns (bool initialized, uint16 index, uint16 cardinality, uint16 cardinalityNext); /// @notice Returns data about a specific observation index /// @param pool The pool address of the observations array to fetch /// @param index The element of the observations array to fetch /// @dev You most likely want to use #observe() instead of this method to get an observation as of some amount of time /// ago, rather than at a specific index in the array. /// @return blockTimestamp The timestamp of the observation, /// Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the observation timestamp, /// Returns initialized whether the observation has been initialized and the values are safe to use function getObservationAt(address pool, uint256 index) external view returns ( uint32 blockTimestamp, int56 tickCumulative, bool initialized ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; interface IRouterTokenHelper { /// @notice Unwraps the contract's WETH balance and sends it to recipient as ETH. /// @dev The minAmount parameter prevents malicious contracts from stealing WETH from users. /// @param minAmount The minimum amount of WETH to unwrap /// @param recipient The address receiving ETH function unwrapWeth(uint256 minAmount, address recipient) external payable; /// @notice Refunds any ETH balance held by this contract to the `msg.sender` /// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps /// that use ether for the input amount function refundEth() external payable; /// @notice Transfers the full amount of a token held by this contract to recipient /// @dev The minAmount parameter prevents malicious contracts from stealing the token from users /// @param token The contract address of the token which will be transferred to `recipient` /// @param minAmount The minimum amount of token required for a transfer /// @param recipient The destination address of the token function transferAllTokens( address token, uint256 minAmount, address recipient ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; interface IBasePositionManagerEvents { /// @notice Emitted when a token is minted for a given position /// @param tokenId the newly minted tokenId /// @param poolId poolId of the token /// @param liquidity liquidity minted to the position range /// @param amount0 token0 quantity needed to mint the liquidity /// @param amount1 token1 quantity needed to mint the liquidity event MintPosition( uint256 indexed tokenId, uint80 indexed poolId, uint128 liquidity, uint256 amount0, uint256 amount1 ); /// @notice Emitted when a token is burned /// @param tokenId id of the token event BurnPosition(uint256 indexed tokenId); /// @notice Emitted when add liquidity /// @param tokenId id of the token /// @param liquidity the increase amount of liquidity /// @param amount0 token0 quantity needed to increase liquidity /// @param amount1 token1 quantity needed to increase liquidity /// @param additionalRTokenOwed additional rToken earned event AddLiquidity( uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1, uint256 additionalRTokenOwed ); /// @notice Emitted when remove liquidity /// @param tokenId id of the token /// @param liquidity the decease amount of liquidity /// @param amount0 token0 quantity returned when remove liquidity /// @param amount1 token1 quantity returned when remove liquidity /// @param additionalRTokenOwed additional rToken earned event RemoveLiquidity( uint256 indexed tokenId, uint128 liquidity, uint256 amount0, uint256 amount1, uint256 additionalRTokenOwed ); /// @notice Emitted when burn position's RToken /// @param tokenId id of the token /// @param rTokenBurn amount of position's RToken burnt event BurnRToken(uint256 indexed tokenId, uint256 rTokenBurn); /// @notice Emitted when sync fee growth /// @param tokenId id of the token /// @param additionalRTokenOwed additional rToken earned event SyncFeeGrowth(uint256 indexed tokenId, uint256 additionalRTokenOwed); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.8.0; import {IERC721} from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; import {IERC721Enumerable} from '@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol'; /// @title ERC721 with permit /// @notice Extension to ERC721 that includes a permit function for signature based approvals interface IERC721Permit is IERC721, IERC721Enumerable { /// @notice The permit typehash used in the permit signature /// @return The typehash for the permit function PERMIT_TYPEHASH() external pure returns (bytes32); /// @notice The domain separator used in the permit signature /// @return The domain seperator used in encoding of permit signature function DOMAIN_SEPARATOR() external view returns (bytes32); /// @notice Approve of a specific token ID for spending by spender via signature /// @param spender The account that is being approved /// @param tokenId The ID of the token that is being approved for spending /// @param deadline The deadline timestamp by which the call must be mined for the approve to work /// @param v Must produce valid secp256k1 signature from the holder along with `r` and `s` /// @param r Must produce valid secp256k1 signature from the holder along with `v` and `s` /// @param s Must produce valid secp256k1 signature from the holder along with `r` and `v` function permit( address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @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); }
// SPDX-License-Identifier: MIT 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`, 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 be 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: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * 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 Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @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 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); /** * @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; }
// SPDX-License-Identifier: MIT 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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
{ "optimizer": { "enabled": true, "runs": 100000 }, "metadata": { "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[{"internalType":"contract IPoolStorage","name":"pool","type":"address"}],"name":"getAllTicks","outputs":[{"internalType":"int24[]","name":"allTicks","type":"int24[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPoolStorage","name":"pool","type":"address"},{"internalType":"int24","name":"tick","type":"int24"}],"name":"getNearestInitializedTicks","outputs":[{"internalType":"int24","name":"previous","type":"int24"},{"internalType":"int24","name":"next","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IPoolStorage","name":"pool","type":"address"},{"internalType":"int24","name":"startTick","type":"int24"},{"internalType":"uint32","name":"length","type":"uint32"}],"name":"getTicksInRange","outputs":[{"internalType":"int24[]","name":"allTicks","type":"int24[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IBasePositionManager","name":"posManager","type":"address"},{"internalType":"contract IPoolStorage","name":"pool","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTotalFeesOwedToPosition","outputs":[{"internalType":"uint256","name":"token0Owed","type":"uint256"},{"internalType":"uint256","name":"token1Owed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IBasePositionManager","name":"posManager","type":"address"},{"internalType":"contract IPoolStorage","name":"pool","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTotalRTokensOwedToPosition","outputs":[{"internalType":"uint256","name":"rTokenOwed","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50612213806100206000396000f3fe608060405234801561001057600080fd5b50600436106100675760003560e01c80636163c59c116100505780636163c59c146100b25780636bea4865146100da578063e5a9cc56146100ed57600080fd5b806304415a001461006c578063529eebbe14610092575b600080fd5b61007f61007a366004611a4d565b61011a565b6040519081526020015b60405180910390f35b6100a56100a0366004611a8e565b610372565b6040516100899190611aab565b6100c56100c0366004611a4d565b61060d565b60408051928352602083019190915201610089565b6100a56100e8366004611b01565b610996565b6101006100fb366004611b55565b610db2565b60408051600293840b81529190920b602082015201610089565b6040517f99fbab8800000000000000000000000000000000000000000000000000000000815260048101829052600090819073ffffffffffffffffffffffffffffffffffffffff8616906399fbab88906024016101606040518083038186803b15801561018657600080fd5b505afa15801561019a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101be9190611d13565b5060408082015190517f4bfe339800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015292935069ffffffffffffffffffff90911691871690634bfe33989060240160206040518083038186803b15801561023d57600080fd5b505afa158015610251573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102759190611de3565b69ffffffffffffffffffff16146102ed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f746f6b656e496420616e6420706f6f6c20646f6e74206d61746368000000000060448201526064015b60405180910390fd5b60006102f88561125e565b5090506000610308868484611474565b90508260e0015181146103645760008360e001518203905061034e8460a001516fffffffffffffffffffffffffffffffff16826c010000000000000000000000006116a3565b8460c00181815161035f9190611e2d565b905250505b505060c00151949350505050565b606060008273ffffffffffffffffffffffffffffffffffffffff166348626a8c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156103bc57600080fd5b505afa1580156103d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103f49190611e45565b600161041f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611e62565b6104299190611ea1565b6104339190611f05565b60020b60026104429190611fa0565b61044d906003611e2d565b90508063ffffffff1667ffffffffffffffff81111561046e5761046e611b8e565b604051908082528060200260200182016040528015610497578160200160208202803683370190505b50915060007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618905080836000815181106104d3576104d3611fdd565b60029290920b6020928302919091019091015260015b6105127ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611e62565b60020b8260020b1215610605576040517fc0ac75cf000000000000000000000000000000000000000000000000000000008152600283900b600482015273ffffffffffffffffffffffffffffffffffffffff86169063c0ac75cf90602401604080518083038186803b15801561058757600080fd5b505afa15801561059b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bf919061200c565b90508092505081848263ffffffff16815181106105de576105de611fdd565b602002602001019060020b908160020b8152505080806105fd9061203b565b9150506104e9565b505050919050565b60008060008573ffffffffffffffffffffffffffffffffffffffff166399fbab88856040518263ffffffff1660e01b815260040161064d91815260200190565b6101606040518083038186803b15801561066657600080fd5b505afa15801561067a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069e9190611d13565b5060408082015190517f4bfe339800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff888116600483015292935069ffffffffffffffffffff90911691881690634bfe33989060240160206040518083038186803b15801561071d57600080fd5b505afa158015610731573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107559190611de3565b69ffffffffffffffffffff16146107c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f746f6b656e496420616e6420706f6f6c20646f6e74206d61746368000000000060448201526064016102e4565b6000806107d48761125e565b9150915060006107e5888585611474565b90508360e0015181146108415760008460e001518203905061082b8560a001516fffffffffffffffffffffffffffffffff16826c010000000000000000000000006116a3565b8560c00181815161083c9190611e2d565b905250505b60008873ffffffffffffffffffffffffffffffffffffffff1663ab612f2b6040518163ffffffff1660e01b815260040160606040518083038186803b15801561088957600080fd5b505afa15801561089d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c1919061205f565b5091505060006108e88660c00151836fffffffffffffffffffffffffffffffff16866116a3565b905060008a73ffffffffffffffffffffffffffffffffffffffff1663217ac2376040518163ffffffff1660e01b815260040160806040518083038186803b15801561093257600080fd5b505afa158015610946573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061096a91906120a2565b50505090506109798183611839565b98506109858183611872565b975050505050505050935093915050565b6040517fc0ac75cf000000000000000000000000000000000000000000000000000000008152600283900b6004820152606090600090819073ffffffffffffffffffffffffffffffffffffffff87169063c0ac75cf90602401604080518083038186803b158015610a0657600080fd5b505afa158015610a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3e919061200c565b915091508160020b6000148015610a5857508060020b6000145b15610a64575050610dab565b600063ffffffff8516610c225760008773ffffffffffffffffffffffffffffffffffffffff166348626a8c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ab957600080fd5b505afa158015610acd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af19190611e45565b9050600287900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276181415610b8057806001610b4b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611e62565b610b559190611ea1565b610b5f9190611f05565b60020b6002610b6e9190611fa0565b610b79906003611e2d565b9150610c1c565b610ba97ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611e62565b60020b8760020b1415610bbf5760019150610c1c565b80876001610bec7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611e62565b610bf69190611ea1565b610c009190611ea1565b610c0a9190611f05565b60020b6002610c199190612106565b91505b50610c25565b50835b8063ffffffff1667ffffffffffffffff811115610c4457610c44611b8e565b604051908082528060200260200182016040528015610c6d578160200160208202803683370190505b50935060005b8163ffffffff168163ffffffff161015610da65786858263ffffffff1681518110610ca057610ca0611fdd565b602002602001019060020b908160020b815250507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618610cde90611e62565b60020b8760020b1415610cf057610da6565b6040517fc0ac75cf000000000000000000000000000000000000000000000000000000008152600288900b600482015273ffffffffffffffffffffffffffffffffffffffff89169063c0ac75cf90602401604080518083038186803b158015610d5857600080fd5b505afa158015610d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d90919061200c565b9750819050610d9e8161203b565b915050610c73565b505050505b9392505050565b600080600283900b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2761813801590610e175750610e0d7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611e62565b60020b8360020b13155b610e7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f7469636b206e6f7420696e2072616e676500000000000000000000000000000060448201526064016102e4565b6040517fc0ac75cf000000000000000000000000000000000000000000000000000000008152600284900b600482015273ffffffffffffffffffffffffffffffffffffffff85169063c0ac75cf90602401604080518083038186803b158015610ee557600080fd5b505afa158015610ef9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1d919061200c565b9092509050600282900b151580610f3857508060020b600014155b15610f4257611257565b60008360020b13156110d957610f777ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff27618611e62565b91505b8260020b8260020b1315611030576040517fc0ac75cf000000000000000000000000000000000000000000000000000000008152600283900b600482015273ffffffffffffffffffffffffffffffffffffffff85169063c0ac75cf90602401604080518083038186803b158015610ff057600080fd5b505afa158015611004573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611028919061200c565b509150610f7a565b6040517fc0ac75cf000000000000000000000000000000000000000000000000000000008152600283900b600482015273ffffffffffffffffffffffffffffffffffffffff85169063c0ac75cf90602401604080518083038186803b15801561109857600080fd5b505afa1580156110ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d0919061200c565b91506112579050565b507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff276185b8260020b8160020b12156111b3576040517fc0ac75cf000000000000000000000000000000000000000000000000000000008152600282900b600482015273ffffffffffffffffffffffffffffffffffffffff85169063c0ac75cf90602401604080518083038186803b15801561117257600080fd5b505afa158015611186573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111aa919061200c565b91506110fc9050565b6040517fc0ac75cf000000000000000000000000000000000000000000000000000000008152600282900b600482015273ffffffffffffffffffffffffffffffffffffffff85169063c0ac75cf90602401604080518083038186803b15801561121b57600080fd5b505afa15801561122f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611253919061200c565b5091505b9250929050565b60008060008060008573ffffffffffffffffffffffffffffffffffffffff1663ab612f2b6040518163ffffffff1660e01b815260040160606040518083038186803b1580156112ac57600080fd5b505afa1580156112c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112e4919061205f565b9250925092508573ffffffffffffffffffffffffffffffffffffffff166372cc51486040518163ffffffff1660e01b815260040160206040518083038186803b15801561133057600080fd5b505afa158015611344573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611368919061212e565b94508573ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156113b057600080fd5b505afa1580156113c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e8919061212e565b9350600061141c836fffffffffffffffffffffffffffffffff16836fffffffffffffffffffffffffffffffff1686886118a2565b9050801561146b5761142e8186611e2d565b945061143a87826118fd565b9050611466816c01000000000000000000000000866fffffffffffffffffffffffffffffffff166116a3565b860195505b50505050915091565b60608201516040517ff30dba9300000000000000000000000000000000000000000000000000000000815260029190910b6004820152600090819073ffffffffffffffffffffffffffffffffffffffff86169063f30dba939060240160806040518083038186803b1580156114e857600080fd5b505afa1580156114fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115209190612147565b5060808701516040517ff30dba9300000000000000000000000000000000000000000000000000000000815260029190910b60048201529093506000925073ffffffffffffffffffffffffffffffffffffffff8816915063f30dba939060240160806040518083038186803b15801561159857600080fd5b505afa1580156115ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d09190612147565b509250505060008673ffffffffffffffffffffffffffffffffffffffff1663217ac2376040518163ffffffff1660e01b815260040160806040518083038186803b15801561161d57600080fd5b505afa158015611631573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165591906120a2565b5050915050856060015160020b8160020b1215611676578183039350611699565b856080015160020b8160020b12611691578282039350611699565b818386030393505b5050509392505050565b600080807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8587098587029250828110838203039150508060001415611758576000841161174d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f302064656e6f6d0000000000000000000000000000000000000000000000000060448201526064016102e4565b508290049050610dab565b8084116117c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f64656e6f6d203c3d2070726f643100000000000000000000000000000000000060448201526064016102e4565b60008486880980840393811190920391905060006117e186196001611e2d565b8616958690049560026003880281188089028203028089028203028089028203028089028203028089028203028089029091030260008290038290046001019490940294049390931791909102925050509392505050565b6000611869826c010000000000000000000000008573ffffffffffffffffffffffffffffffffffffffff166116a3565b90505b92915050565b6000611869828473ffffffffffffffffffffffffffffffffffffffff166c010000000000000000000000006116a3565b6000806118e66fffffffffffffffffffffffffffffffff85166118c5878961219d565b6118e1896fffffffffffffffffffffffffffffffff8916611e2d565b6116a3565b90506118f38382876116a3565b9695505050505050565b6000808373ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b815260040160206040518083038186803b15801561194657600080fd5b505afa15801561195a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197e91906121b4565b73ffffffffffffffffffffffffffffffffffffffff166398c47e8c6040518163ffffffff1660e01b8152600401604080518083038186803b1580156119c257600080fd5b505afa1580156119d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fa91906121d1565b91505062ffffff8116611a10578291505061186c565b620186a062ffffff9190911683020490910392915050565b73ffffffffffffffffffffffffffffffffffffffff81168114611a4a57600080fd5b50565b600080600060608486031215611a6257600080fd5b8335611a6d81611a28565b92506020840135611a7d81611a28565b929592945050506040919091013590565b600060208284031215611aa057600080fd5b8135610dab81611a28565b6020808252825182820181905260009190848201906040850190845b81811015611ae657835160020b83529284019291840191600101611ac7565b50909695505050505050565b8060020b8114611a4a57600080fd5b600080600060608486031215611b1657600080fd5b8335611b2181611a28565b92506020840135611b3181611af2565b9150604084013563ffffffff81168114611b4a57600080fd5b809150509250925092565b60008060408385031215611b6857600080fd5b8235611b7381611a28565b91506020830135611b8381611af2565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715611c08577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405290565b8051611c1981611a28565b919050565b805169ffffffffffffffffffff81168114611c1957600080fd5b8051611c1981611af2565b80516fffffffffffffffffffffffffffffffff81168114611c1957600080fd5b805162ffffff81168114611c1957600080fd5b600060608284031215611c8857600080fd5b6040516060810181811067ffffffffffffffff82111715611cd2577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80604052508091508251611ce581611a28565b8152611cf360208401611c63565b60208201526040830151611d0681611a28565b6040919091015292915050565b600080828403610160811215611d2857600080fd5b61010080821215611d3857600080fd5b611d40611bbd565b915084516bffffffffffffffffffffffff81168114611d5e57600080fd5b8252611d6c60208601611c0e565b6020830152611d7d60408601611c1e565b6040830152611d8e60608601611c38565b6060830152611d9f60808601611c38565b6080830152611db060a08601611c43565b60a083015260c085015160c083015260e085015160e0830152819350611dd886828701611c76565b925050509250929050565b600060208284031215611df557600080fd5b61186982611c1e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115611e4057611e40611dfe565b500190565b600060208284031215611e5757600080fd5b8151610dab81611af2565b60008160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000811415611e9857611e98611dfe565b60000392915050565b60008160020b8360020b60008112817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000001831281151615611ee457611ee4611dfe565b81627fffff018313811615611efb57611efb611dfe565b5090039392505050565b60008160020b8360020b80611f43577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000083141615611f9757611f97611dfe565b90059392505050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611fd857611fd8611dfe565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000806040838503121561201f57600080fd5b825161202a81611af2565b6020840151909250611b8381611af2565b600063ffffffff8083168181141561205557612055611dfe565b6001019392505050565b60008060006060848603121561207457600080fd5b61207d84611c43565b925061208b60208501611c43565b915061209960408501611c43565b90509250925092565b600080600080608085870312156120b857600080fd5b84516120c381611a28565b60208601519094506120d481611af2565b60408601519093506120e581611af2565b606086015190925080151581146120fb57600080fd5b939692955090935050565b600063ffffffff80831681851680830382111561212557612125611dfe565b01949350505050565b60006020828403121561214057600080fd5b5051919050565b6000806000806080858703121561215d57600080fd5b61216685611c43565b9350602085015180600f0b811461217c57600080fd5b6040860151909350915061219260608601611c43565b905092959194509250565b6000828210156121af576121af611dfe565b500390565b6000602082840312156121c657600080fd5b8151610dab81611a28565b600080604083850312156121e457600080fd5b82516121ef81611a28565b91506121fd60208401611c63565b9050925092905056fea164736f6c6343000809000a
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.