Polygon Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 12,800 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 70630218 | 10 hrs ago | IN | 0 POL | 0.01438401 | ||||
Withdraw | 70628243 | 11 hrs ago | IN | 0 POL | 0.01460727 | ||||
Withdraw | 70609931 | 22 hrs ago | IN | 0 POL | 0.02240344 | ||||
Withdraw | 70602673 | 26 hrs ago | IN | 0 POL | 0.0106455 | ||||
Approve | 70597293 | 29 hrs ago | IN | 0 POL | 0.00072738 | ||||
Withdraw | 70580593 | 39 hrs ago | IN | 0 POL | 0.01503158 | ||||
Withdraw | 70549922 | 2 days ago | IN | 0 POL | 0.01466607 | ||||
Withdraw | 70531516 | 2 days ago | IN | 0 POL | 0.01330374 | ||||
Withdraw | 70490098 | 3 days ago | IN | 0 POL | 0.0159034 | ||||
Withdraw | 70478988 | 4 days ago | IN | 0 POL | 0.01606887 | ||||
Withdraw | 70457676 | 4 days ago | IN | 0 POL | 0.01524753 | ||||
Withdraw | 70451923 | 4 days ago | IN | 0 POL | 0.01465266 | ||||
Withdraw | 70430771 | 5 days ago | IN | 0 POL | 0.01592079 | ||||
Withdraw | 70430046 | 5 days ago | IN | 0 POL | 0.01546176 | ||||
Withdraw | 70427473 | 5 days ago | IN | 0 POL | 0.01485465 | ||||
Withdraw | 70416652 | 5 days ago | IN | 0 POL | 0.01580286 | ||||
Withdraw | 70381312 | 6 days ago | IN | 0 POL | 0.01495229 | ||||
Withdraw | 70379093 | 6 days ago | IN | 0 POL | 0.01582077 | ||||
Approve | 70363259 | 7 days ago | IN | 0 POL | 0.00075235 | ||||
Withdraw | 70349440 | 7 days ago | IN | 0 POL | 0.01529628 | ||||
Approve | 70339380 | 7 days ago | IN | 0 POL | 0.00072738 | ||||
Approve | 70306097 | 8 days ago | IN | 0 POL | 0.00072738 | ||||
Withdraw | 70298351 | 8 days ago | IN | 0 POL | 0.0150817 | ||||
Permit | 70288611 | 8 days ago | IN | 0 POL | 0.00164433 | ||||
Withdraw | 70285257 | 8 days ago | IN | 0 POL | 0.01578791 |
Loading...
Loading
Contract Name:
Hypervisor
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 800 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.7.6; import "@openzeppelin/contracts/math/Math.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/math/SignedSafeMath.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/drafts/ERC20Permit.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "./algebra/interfaces/callback/IAlgebraMintCallback.sol"; import "./algebra/interfaces/IAlgebraPool.sol"; import "./algebra/libraries/TickMath.sol"; import "@uniswap/v3-core/contracts/libraries/FullMath.sol"; import "@uniswap/v3-periphery/contracts/libraries/LiquidityAmounts.sol"; /// @title Hypervisor 1.3.1 /// @notice A Uniswap V2-like interface with fungible liquidity to Quickswap /// which allows for arbitrary liquidity provision: one-sided, lop-sided, and balanced contract Hypervisor is IAlgebraMintCallback, ERC20Permit, ReentrancyGuard { using SafeERC20 for IERC20; using SafeMath for uint256; using SignedSafeMath for int256; IAlgebraPool public pool; IERC20 public token0; IERC20 public token1; uint8 public fee = 7; int24 public tickSpacing; int24 public baseLower; int24 public baseUpper; int24 public limitLower; int24 public limitUpper; address public owner; uint256 public deposit0Max; uint256 public deposit1Max; uint256 public maxTotalSupply; address public whitelistedAddress; address public feeRecipient; bool public directDeposit; /// enter uni on deposit (avoid if client uses public rpc) uint256 public constant PRECISION = 1e36; bool mintCalled; event Deposit( address indexed sender, address indexed to, uint256 shares, uint256 amount0, uint256 amount1 ); event Withdraw( address indexed sender, address indexed to, uint256 shares, uint256 amount0, uint256 amount1 ); event Rebalance( int24 tick, uint256 totalAmount0, uint256 totalAmount1, uint256 feeAmount0, uint256 feeAmount1, uint256 totalSupply ); event ZeroBurn(uint8 fee, uint256 fees0, uint256 fees1); event SetFee(uint8 newFee); /// @param _pool Uniswap V3 pool for which liquidity is managed /// @param _owner Owner of the Hypervisor constructor( address _pool, address _owner, string memory name, string memory symbol ) ERC20Permit(name) ERC20(name, symbol) { require(_pool != address(0)); require(_owner != address(0)); pool = IAlgebraPool(_pool); token0 = IERC20(pool.token0()); token1 = IERC20(pool.token1()); require(address(token0) != address(0)); require(address(token1) != address(0)); tickSpacing = pool.tickSpacing(); owner = _owner; maxTotalSupply = 0; /// no cap deposit0Max = uint256(-1); deposit1Max = uint256(-1); } /// @notice Deposit tokens /// @param deposit0 Amount of token0 transfered from sender to Hypervisor /// @param deposit1 Amount of token1 transfered from sender to Hypervisor /// @param to Address to which liquidity tokens are minted /// @param from Address from which asset tokens are transferred /// @param inMin min spend for directDeposit is true /// @return shares Quantity of liquidity tokens minted as a result of deposit function deposit( uint256 deposit0, uint256 deposit1, address to, address from, uint256[4] memory inMin ) nonReentrant external returns (uint256 shares) { require(deposit0 > 0 || deposit1 > 0); require(deposit0 <= deposit0Max && deposit1 <= deposit1Max); require(to != address(0) && to != address(this), "to"); require(msg.sender == whitelistedAddress, "WHE"); /// update fees zeroBurn(); uint160 sqrtPrice = TickMath.getSqrtRatioAtTick(currentTick()); uint256 price = FullMath.mulDiv(uint256(sqrtPrice).mul(uint256(sqrtPrice)), PRECISION, 2**(96 * 2)); (uint256 pool0, uint256 pool1) = getTotalAmounts(); shares = deposit1.add(deposit0.mul(price).div(PRECISION)); if (deposit0 > 0) { token0.safeTransferFrom(from, address(this), deposit0); } if (deposit1 > 0) { token1.safeTransferFrom(from, address(this), deposit1); } uint256 total = totalSupply(); if (total != 0) { uint256 pool0PricedInToken1 = pool0.mul(price).div(PRECISION); shares = shares.mul(total).div(pool0PricedInToken1.add(pool1)); if (directDeposit) { uint128 liquidity = _liquidityForAmounts( baseLower, baseUpper, token0.balanceOf(address(this)), token1.balanceOf(address(this)) ); _mintLiquidity(baseLower, baseUpper, liquidity, address(this), inMin[0], inMin[1]); liquidity = _liquidityForAmounts( limitLower, limitUpper, token0.balanceOf(address(this)), token1.balanceOf(address(this)) ); _mintLiquidity(limitLower, limitUpper, liquidity, address(this), inMin[2], inMin[3]); } } _mint(to, shares); emit Deposit(from, to, shares, deposit0, deposit1); /// Check total supply cap not exceeded. A value of 0 means no limit. require(maxTotalSupply == 0 || total <= maxTotalSupply, "max"); } function _zeroBurn(int24 tickLower, int24 tickUpper) internal returns(uint128 liquidity) { /// update fees for inclusion (liquidity, ,) = _position(tickLower, tickUpper); if(liquidity > 0) { pool.burn(tickLower, tickUpper, 0); (uint256 owed0, uint256 owed1) = pool.collect(address(this), tickLower, tickUpper, type(uint128).max, type(uint128).max); emit ZeroBurn(fee, owed0, owed1); if (owed0.div(fee) > 0 && token0.balanceOf(address(this)) > 0) token0.safeTransfer(feeRecipient, owed0.div(fee)); if (owed1.div(fee) > 0 && token1.balanceOf(address(this)) > 0) token1.safeTransfer(feeRecipient, owed1.div(fee)); } } /// @notice Update fees of the positions /// @return baseLiquidity Fee of base position /// @return limitLiquidity Fee of limit position function zeroBurn() internal returns(uint128 baseLiquidity, uint128 limitLiquidity) { baseLiquidity = _zeroBurn(baseLower, baseUpper); limitLiquidity = _zeroBurn(limitLower, limitUpper); } /// @notice Pull liquidity tokens from liquidity and receive the tokens /// @param shares Number of liquidity tokens to pull from liquidity /// @param tickLower lower tick /// @param tickUpper upper tick /// @param amountMin min outs /// @return amount0 amount of token0 received from base position /// @return amount1 amount of token1 received from base position function pullLiquidity( int24 tickLower, int24 tickUpper, uint128 shares, uint256[2] memory amountMin ) external onlyOwner returns (uint256 amount0, uint256 amount1) { _zeroBurn(tickLower, tickUpper); (amount0, amount1) = _burnLiquidity( tickLower, tickUpper, _liquidityForShares(tickLower, tickUpper, shares), address(this), false, amountMin[0], amountMin[1] ); } /// @param shares Number of liquidity tokens to redeem as pool assets /// @param to Address to which redeemed pool assets are sent /// @param from Address from which liquidity tokens are sent /// @param minAmounts min amount0,1 returned for shares of liq /// @return amount0 Amount of token0 redeemed by the submitted liquidity tokens /// @return amount1 Amount of token1 redeemed by the submitted liquidity tokens function withdraw( uint256 shares, address to, address from, uint256[4] memory minAmounts ) nonReentrant external returns (uint256 amount0, uint256 amount1) { require(shares > 0, "shares"); require(to != address(0), "to"); /// update fees zeroBurn(); /// Withdraw liquidity from Uniswap pool (uint256 base0, uint256 base1) = _burnLiquidity( baseLower, baseUpper, _liquidityForShares(baseLower, baseUpper, shares), to, false, minAmounts[0], minAmounts[1] ); (uint256 limit0, uint256 limit1) = _burnLiquidity( limitLower, limitUpper, _liquidityForShares(limitLower, limitUpper, shares), to, false, minAmounts[2], minAmounts[3] ); // Push tokens proportional to unused balances uint256 unusedAmount0 = token0.balanceOf(address(this)).mul(shares).div(totalSupply()); uint256 unusedAmount1 = token1.balanceOf(address(this)).mul(shares).div(totalSupply()); if (unusedAmount0 > 0) token0.safeTransfer(to, unusedAmount0); if (unusedAmount1 > 0) token1.safeTransfer(to, unusedAmount1); amount0 = base0.add(limit0).add(unusedAmount0); amount1 = base1.add(limit1).add(unusedAmount1); require( from == msg.sender, "own"); _burn(from, shares); emit Withdraw(from, to, shares, amount0, amount1); } /// @param _baseLower The lower tick of the base position /// @param _baseUpper The upper tick of the base position /// @param _limitLower The lower tick of the limit position /// @param _limitUpper The upper tick of the limit position /// @param inMin min spend /// @param outMin min amount0,1 returned for shares of liq /// @param _feeRecipient Address of recipient of 10% of earned fees since last rebalance function rebalance( int24 _baseLower, int24 _baseUpper, int24 _limitLower, int24 _limitUpper, address _feeRecipient, uint256[4] memory inMin, uint256[4] memory outMin ) nonReentrant external onlyOwner { require( _baseLower < _baseUpper && _baseLower % tickSpacing == 0 && _baseUpper % tickSpacing == 0 ); require( _limitLower < _limitUpper && _limitLower % tickSpacing == 0 && _limitUpper % tickSpacing == 0 ); require( _limitUpper != _baseUpper || _limitLower != _baseLower ); require(_feeRecipient != address(0)); feeRecipient = _feeRecipient; /// update fees zeroBurn(); /// Withdraw all liquidity and collect all fees from Uniswap pool (uint128 baseLiquidity, uint256 feesLimit0, uint256 feesLimit1) = _position(baseLower, baseUpper); (uint128 limitLiquidity, uint256 feesBase0, uint256 feesBase1) = _position(limitLower, limitUpper); _burnLiquidity(baseLower, baseUpper, baseLiquidity, address(this), true, outMin[0], outMin[1]); _burnLiquidity(limitLower, limitUpper, limitLiquidity, address(this), true, outMin[2], outMin[3]); emit Rebalance( currentTick(), token0.balanceOf(address(this)), token1.balanceOf(address(this)), feesBase0.add(feesLimit0), feesBase1.add(feesLimit1), totalSupply() ); baseLower = _baseLower; baseUpper = _baseUpper; baseLiquidity = _liquidityForAmounts( baseLower, baseUpper, token0.balanceOf(address(this)), token1.balanceOf(address(this)) ); _mintLiquidity(baseLower, baseUpper, baseLiquidity, address(this), inMin[0], inMin[1]); limitLower = _limitLower; limitUpper = _limitUpper; limitLiquidity = _liquidityForAmounts( limitLower, limitUpper, token0.balanceOf(address(this)), token1.balanceOf(address(this)) ); _mintLiquidity(limitLower, limitUpper, limitLiquidity, address(this), inMin[2], inMin[3]); } /// @notice Compound pending fees /// @param inMin min spend /// @return baseToken0Owed Pending fees of base token0 /// @return baseToken1Owed Pending fees of base token1 /// @return limitToken0Owed Pending fees of limit token0 /// @return limitToken1Owed Pending fees of limit token1 function compound(uint256[4] memory inMin) external onlyOwner returns ( uint128 baseToken0Owed, uint128 baseToken1Owed, uint128 limitToken0Owed, uint128 limitToken1Owed ) { // update fees for compounding zeroBurn(); uint128 liquidity = _liquidityForAmounts( baseLower, baseUpper, token0.balanceOf(address(this)), token1.balanceOf(address(this)) ); _mintLiquidity(baseLower, baseUpper, liquidity, address(this), inMin[0], inMin[1]); liquidity = _liquidityForAmounts( limitLower, limitUpper, token0.balanceOf(address(this)), token1.balanceOf(address(this)) ); _mintLiquidity(limitLower, limitUpper, liquidity, address(this), inMin[2], inMin[3]); } /// @notice Add Liquidity function addLiquidity( int24 tickLower, int24 tickUpper, uint256 amount0, uint256 amount1, uint256[2] memory inMin ) public onlyOwner { _zeroBurn(tickLower, tickUpper); uint128 liquidity = _liquidityForAmounts(tickLower, tickUpper, amount0, amount1); _mintLiquidity(tickLower, tickUpper, liquidity, address(this), inMin[0], inMin[1]); } /// @notice Adds the liquidity for the given position /// @param tickLower The lower tick of the position in which to add liquidity /// @param tickUpper The upper tick of the position in which to add liquidity /// @param liquidity The amount of liquidity to mint /// @param payer Payer Data /// @param amount0Min Minimum amount of token0 that should be paid /// @param amount1Min Minimum amount of token1 that should be paid function _mintLiquidity( int24 tickLower, int24 tickUpper, uint128 liquidity, address payer, uint256 amount0Min, uint256 amount1Min ) internal { if (liquidity > 0) { mintCalled = true; (uint256 amount0, uint256 amount1, ) = pool.mint( address(this), address(this), tickLower, tickUpper, liquidity, abi.encode(payer) ); require(amount0 >= amount0Min && amount1 >= amount1Min, 'PSC'); } } /// @notice Burn liquidity from the sender and collect tokens owed for the liquidity /// @param tickLower The lower tick of the position for which to burn liquidity /// @param tickUpper The upper tick of the position for which to burn liquidity /// @param liquidity The amount of liquidity to burn /// @param to The address which should receive the fees collected /// @param collectAll If true, collect all tokens owed in the pool, else collect the owed tokens of the burn /// @return amount0 The amount of fees collected in token0 /// @return amount1 The amount of fees collected in token1 function _burnLiquidity( int24 tickLower, int24 tickUpper, uint128 liquidity, address to, bool collectAll, uint256 amount0Min, uint256 amount1Min ) internal returns (uint256 amount0, uint256 amount1) { if (liquidity > 0) { /// Burn liquidity (uint256 owed0, uint256 owed1) = pool.burn(tickLower, tickUpper, liquidity); require(owed0 >= amount0Min && owed1 >= amount1Min, "PSC"); // Collect amount owed uint128 collect0 = collectAll ? type(uint128).max : _uint128Safe(owed0); uint128 collect1 = collectAll ? type(uint128).max : _uint128Safe(owed1); if (collect0 > 0 || collect1 > 0) { (amount0, amount1) = pool.collect(to, tickLower, tickUpper, collect0, collect1); } } } /// @notice Get the liquidity amount for given liquidity tokens /// @param tickLower The lower tick of the position /// @param tickUpper The upper tick of the position /// @param shares Shares of position /// @return The amount of liquidity toekn for shares function _liquidityForShares( int24 tickLower, int24 tickUpper, uint256 shares ) internal view returns (uint128) { (uint128 position, , ) = _position(tickLower, tickUpper); return _uint128Safe(uint256(position).mul(shares).div(totalSupply())); } /// @notice Get the info of the given position /// @param tickLower The lower tick of the position /// @param tickUpper The upper tick of the position /// @return liquidity The amount of liquidity of the position /// @return tokensOwed0 Amount of token0 owed /// @return tokensOwed1 Amount of token1 owed function _position(int24 tickLower, int24 tickUpper) internal view returns ( uint128 liquidity, uint128 tokensOwed0, uint128 tokensOwed1 ) { bytes32 positionKey; address This = address(this); assembly { positionKey := or(shl(24, or(shl(24, This), and(tickLower, 0xFFFFFF))), and(tickUpper, 0xFFFFFF)) } (liquidity, , , , tokensOwed0, tokensOwed1) = pool.positions(positionKey); } /// @notice Callback function of uniswapV3Pool mint function algebraMintCallback( uint256 amount0, uint256 amount1, bytes calldata data ) external override { require(msg.sender == address(pool)); require(mintCalled == true); mintCalled = false; if (amount0 > 0) token0.safeTransfer(msg.sender, amount0); if (amount1 > 0) token1.safeTransfer(msg.sender, amount1); } /// @return total0 Quantity of token0 in both positions and unused in the Hypervisor /// @return total1 Quantity of token1 in both positions and unused in the Hypervisor function getTotalAmounts() public view returns (uint256 total0, uint256 total1) { (, uint256 base0, uint256 base1) = getBasePosition(); (, uint256 limit0, uint256 limit1) = getLimitPosition(); total0 = token0.balanceOf(address(this)).add(base0).add(limit0); total1 = token1.balanceOf(address(this)).add(base1).add(limit1); } /// @return liquidity Amount of total liquidity in the base position /// @return amount0 Estimated amount of token0 that could be collected by /// burning the base position /// @return amount1 Estimated amount of token1 that could be collected by /// burning the base position function getBasePosition() public view returns ( uint128 liquidity, uint256 amount0, uint256 amount1 ) { (uint128 positionLiquidity, uint128 tokensOwed0, uint128 tokensOwed1) = _position( baseLower, baseUpper ); (amount0, amount1) = _amountsForLiquidity(baseLower, baseUpper, positionLiquidity); amount0 = amount0.add(uint256(tokensOwed0)); amount1 = amount1.add(uint256(tokensOwed1)); liquidity = positionLiquidity; } /// @return liquidity Amount of total liquidity in the limit position /// @return amount0 Estimated amount of token0 that could be collected by /// burning the limit position /// @return amount1 Estimated amount of token1 that could be collected by /// burning the limit position function getLimitPosition() public view returns ( uint128 liquidity, uint256 amount0, uint256 amount1 ) { (uint128 positionLiquidity, uint128 tokensOwed0, uint128 tokensOwed1) = _position( limitLower, limitUpper ); (amount0, amount1) = _amountsForLiquidity(limitLower, limitUpper, positionLiquidity); amount0 = amount0.add(uint256(tokensOwed0)); amount1 = amount1.add(uint256(tokensOwed1)); liquidity = positionLiquidity; } /// @notice Get the amounts of the given numbers of liquidity tokens /// @param tickLower The lower tick of the position /// @param tickUpper The upper tick of the position /// @param liquidity The amount of liquidity tokens /// @return Amount of token0 and token1 function _amountsForLiquidity( int24 tickLower, int24 tickUpper, uint128 liquidity ) internal view returns (uint256, uint256) { (uint160 sqrtRatioX96, , , , , , ) = pool.globalState(); return LiquidityAmounts.getAmountsForLiquidity( sqrtRatioX96, TickMath.getSqrtRatioAtTick(tickLower), TickMath.getSqrtRatioAtTick(tickUpper), liquidity ); } /// @notice Get the liquidity amount of the given numbers of token0 and token1 /// @param tickLower The lower tick of the position /// @param tickUpper The upper tick of the position /// @param amount0 The amount of token0 /// @param amount0 The amount of token1 /// @return Amount of liquidity tokens function _liquidityForAmounts( int24 tickLower, int24 tickUpper, uint256 amount0, uint256 amount1 ) internal view returns (uint128) { (uint160 sqrtRatioX96, , , , , , ) = pool.globalState(); return LiquidityAmounts.getLiquidityForAmounts( sqrtRatioX96, TickMath.getSqrtRatioAtTick(tickLower), TickMath.getSqrtRatioAtTick(tickUpper), amount0, amount1 ); } /// @return tick Uniswap pool's current price tick function currentTick() public view returns (int24 tick) { (, tick, , , , , ) = pool.globalState(); } function _uint128Safe(uint256 x) internal pure returns (uint128) { assert(x <= type(uint128).max); return uint128(x); } /// @param _address Array of addresses to be appended function setWhitelist(address _address) external onlyOwner { whitelistedAddress = _address; } /// @notice Remove Whitelisted function removeWhitelisted() external onlyOwner { whitelistedAddress = address(0); } /// @notice set fee function setFee(uint8 newFee) external onlyOwner { fee = newFee; emit SetFee(fee); } /// @notice Toggle Direct Deposit function toggleDirectDeposit() external onlyOwner { directDeposit = !directDeposit; } function transferOwnership(address newOwner) external onlyOwner { require(newOwner != address(0)); owner = newOwner; } modifier onlyOwner { require(msg.sender == owner, "only owner"); _; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @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, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @title SignedSafeMath * @dev Signed math operations with safety checks that revert on error. */ library SignedSafeMath { int256 constant private _INT256_MIN = -2**255; /** * @dev Returns the multiplication of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow"); int256 c = a * b; require(c / a == b, "SignedSafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two signed integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(int256 a, int256 b) internal pure returns (int256) { require(b != 0, "SignedSafeMath: division by zero"); require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow"); int256 c = a / b; return c; } /** * @dev Returns the subtraction of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow"); return c; } /** * @dev Returns the addition of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow"); return c; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "./IERC20.sol"; import "../../math/SafeMath.sol"; import "../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.5 <0.8.0; import "../token/ERC20/ERC20.sol"; import "./IERC20Permit.sol"; import "../cryptography/ECDSA.sol"; import "../utils/Counters.sol"; import "./EIP712.sol"; /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { using Counters for Counters.Counter; mapping (address => Counters.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ constructor(string memory name) internal EIP712(name, "1") { } /** * @dev See {IERC20Permit-permit}. */ function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override { // solhint-disable-next-line not-rely-on-time require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256( abi.encode( _PERMIT_TYPEHASH, owner, spender, value, _nonces[owner].current(), deadline ) ); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _nonces[owner].increment(); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 () internal { _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 make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // 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: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Callback for IAlgebraPoolActions#mint /// @notice Any contract that calls IAlgebraPoolActions#mint must implement this interface /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces interface IAlgebraMintCallback { /// @notice Called to `msg.sender` after minting liquidity to a position from IAlgebraPool#mint. /// @dev In the implementation you must pay the pool tokens owed for the minted liquidity. /// The caller of this method must be checked to be a AlgebraPool deployed by the canonical AlgebraFactory. /// @param amount0Owed The amount of token0 due to the pool for the minted liquidity /// @param amount1Owed The amount of token1 due to the pool for the minted liquidity /// @param data Any data passed through by the caller via the IAlgebraPoolActions#mint call function algebraMintCallback( uint256 amount0Owed, uint256 amount1Owed, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; import './pool/IAlgebraPoolImmutables.sol'; import './pool/IAlgebraPoolState.sol'; import './pool/IAlgebraPoolDerivedState.sol'; import './pool/IAlgebraPoolActions.sol'; import './pool/IAlgebraPoolPermissionedActions.sol'; import './pool/IAlgebraPoolEvents.sol'; /** * @title The interface for a Algebra Pool * @dev The pool interface is broken up into many smaller pieces. * Credit to Uniswap Labs under GPL-2.0-or-later license: * https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces */ interface IAlgebraPool is IAlgebraPoolImmutables, IAlgebraPoolState, IAlgebraPoolDerivedState, IAlgebraPoolActions, IAlgebraPoolPermissionedActions, IAlgebraPoolEvents { // used only for combining interfaces }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.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 /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-core/blob/main/contracts/libraries 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 price 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 price) { // get abs value int24 mask = tick >> (24 - 1); uint256 absTick = uint256((tick ^ mask) - mask); require(absTick <= uint256(MAX_TICK), 'T'); 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; 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 price = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); } /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio /// @dev Throws in case price < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may /// ever return. /// @param price 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 price) internal pure returns (int24 tick) { // second inequality must be < because the price can never reach the price at the max tick require(price >= MIN_SQRT_RATIO && price < MAX_SQRT_RATIO, 'R'); uint256 ratio = uint256(price) << 32; uint256 r = ratio; uint256 msb = 0; 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) <= price ? tickHi : tickLow; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.4.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 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 mulDiv( 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); assembly { result := div(prod0, denominator) } return result; } // 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] // 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; // 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) } 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 mulDivRoundingUp( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) > 0) { require(result < type(uint256).max); result++; } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; import '@uniswap/v3-core/contracts/libraries/FullMath.sol'; import '@uniswap/v3-core/contracts/libraries/FixedPoint96.sol'; /// @title Liquidity amount functions /// @notice Provides functions for computing liquidity amounts from token amounts and prices library LiquidityAmounts { /// @notice Downcasts uint256 to uint128 /// @param x The uint258 to be downcasted /// @return y The passed value, downcasted to uint128 function toUint128(uint256 x) private pure returns (uint128 y) { require((y = uint128(x)) == x); } /// @notice Computes the amount of liquidity received for a given amount of token0 and price range /// @dev Calculates amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - sqrt(lower)) /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param amount0 The amount0 being sent in /// @return liquidity The amount of returned liquidity function getLiquidityForAmount0( uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint256 amount0 ) internal pure returns (uint128 liquidity) { if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96); return toUint128(FullMath.mulDiv(amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96)); } /// @notice Computes the amount of liquidity received for a given amount of token1 and price range /// @dev Calculates amount1 / (sqrt(upper) - sqrt(lower)). /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param amount1 The amount1 being sent in /// @return liquidity The amount of returned liquidity function getLiquidityForAmount1( uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint256 amount1 ) internal pure returns (uint128 liquidity) { if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); return toUint128(FullMath.mulDiv(amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96)); } /// @notice Computes the maximum amount of liquidity received for a given amount of token0, token1, the current /// pool prices and the prices at the tick boundaries /// @param sqrtRatioX96 A sqrt price representing the current pool prices /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param amount0 The amount of token0 being sent in /// @param amount1 The amount of token1 being sent in /// @return liquidity The maximum amount of liquidity received function getLiquidityForAmounts( uint160 sqrtRatioX96, uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint256 amount0, uint256 amount1 ) internal pure returns (uint128 liquidity) { if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); if (sqrtRatioX96 <= sqrtRatioAX96) { liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0); } else if (sqrtRatioX96 < sqrtRatioBX96) { uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0); uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1); liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1; } else { liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1); } } /// @notice Computes the amount of token0 for a given amount of liquidity and a price range /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param liquidity The liquidity being valued /// @return amount0 The amount of token0 function getAmount0ForLiquidity( uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint128 liquidity ) internal pure returns (uint256 amount0) { if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); return FullMath.mulDiv( uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96 ) / sqrtRatioAX96; } /// @notice Computes the amount of token1 for a given amount of liquidity and a price range /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param liquidity The liquidity being valued /// @return amount1 The amount of token1 function getAmount1ForLiquidity( uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint128 liquidity ) internal pure returns (uint256 amount1) { if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); return FullMath.mulDiv(liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96); } /// @notice Computes the token0 and token1 value for a given amount of liquidity, the current /// pool prices and the prices at the tick boundaries /// @param sqrtRatioX96 A sqrt price representing the current pool prices /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param liquidity The liquidity being valued /// @return amount0 The amount of token0 /// @return amount1 The amount of token1 function getAmountsForLiquidity( uint160 sqrtRatioX96, uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint128 liquidity ) internal pure returns (uint256 amount0, uint256 amount1) { if (sqrtRatioAX96 > sqrtRatioBX96) (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); if (sqrtRatioX96 <= sqrtRatioAX96) { amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); } else if (sqrtRatioX96 < sqrtRatioBX96) { amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity); amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity); } else { amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../../utils/Context.sol"; import "./IERC20.sol"; import "../../math/SafeMath.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name_, string memory symbol_) public { _name = name_; _symbol = symbol_; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal virtual { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens, * given `owner`'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for `permit`, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length if (signature.length != 65) { revert("ECDSA: invalid signature length"); } // Divide the signature in r, s and v variables bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. // solhint-disable-next-line no-inline-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return recover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover-bytes32-bytes-} that receives the `v`, * `r` and `s` signature fields separately. */ function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (281): 0 < s < secp256k1n ÷ 2 + 1, and for v in (282): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value"); require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value"); // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); require(signer != address(0), "ECDSA: invalid signature"); return signer; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * replicates the behavior of the * https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign[`eth_sign`] * JSON-RPC method. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../math/SafeMath.sol"; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath} * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never * directly accessed. */ library Counters { using SafeMath for uint256; struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { // The {SafeMath} overflow check can be skipped here, see the comment at the top counter._value += 1; } function decrement(Counter storage counter) internal { counter._value = counter._value.sub(1); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712 { /* solhint-disable var-name-mixedcase */ // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) internal { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = _getChainId(); _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view virtual returns (bytes32) { if (_getChainId() == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) { return keccak256( abi.encode( typeHash, name, version, _getChainId(), address(this) ) ); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", _domainSeparatorV4(), structHash)); } function _getChainId() private view returns (uint256 chainId) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 // solhint-disable-next-line no-inline-assembly assembly { chainId := chainid() } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; import '../IDataStorageOperator.sol'; /// @title Pool state that never changes /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces interface IAlgebraPoolImmutables { /** * @notice The contract that stores all the timepoints and can perform actions with them * @return The operator address */ function dataStorageOperator() external view returns (address); /** * @notice The contract that deployed the pool, which must adhere to the IAlgebraFactory interface * @return The contract address */ function factory() external view returns (address); /** * @notice The first of the two tokens of the pool, sorted by address * @return The token contract address */ function token0() external view returns (address); /** * @notice The second of the two tokens of the pool, sorted by address * @return The token contract address */ function token1() external view returns (address); /** * @notice The pool tick spacing * @dev Ticks can only be used at multiples of this value * e.g.: a tickSpacing of 60 means ticks can be initialized every 60th tick, i.e., ..., -120, -60, 0, 60, 120, ... * This value is an int24 to avoid casting even though it is always positive. * @return The tick spacing */ function tickSpacing() external view returns (int24); /** * @notice The maximum amount of position liquidity that can use any tick in the range * @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and * 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 maxLiquidityPerTick() external view returns (uint128); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Pool state that can change /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces interface IAlgebraPoolState { /** * @notice The globalState structure in the pool stores many values but requires only one slot * and is exposed as a single method to save gas when accessed externally. * @return price The current price of the pool as a sqrt(token1/token0) Q64.96 value; * Returns tick The current tick of the pool, i.e. according to the last tick transition that was run; * Returns This value may not always be equal to SqrtTickMath.getTickAtSqrtRatio(price) if the price is on a tick * boundary; * Returns fee The last pool fee value in hundredths of a bip, i.e. 1e-6; * Returns timepointIndex The index of the last written timepoint; * Returns communityFeeToken0 The community fee percentage of the swap fee in thousandths (1e-3) for token0; * Returns communityFeeToken1 The community fee percentage of the swap fee in thousandths (1e-3) for token1; * Returns unlocked Whether the pool is currently locked to reentrancy; */ function globalState() external view returns ( uint160 price, int24 tick, uint16 fee, uint16 timepointIndex, uint8 communityFeeToken0, uint8 communityFeeToken1, bool unlocked ); /** * @notice The fee growth as a Q128.128 fees of token0 collected per unit of liquidity for the entire life of the pool * @dev This value can overflow the uint256 */ function totalFeeGrowth0Token() external view returns (uint256); /** * @notice The fee growth as a Q128.128 fees of token1 collected per unit of liquidity for the entire life of the pool * @dev This value can overflow the uint256 */ function totalFeeGrowth1Token() external view returns (uint256); /** * @notice The currently in range liquidity available to the pool * @dev This value has no relationship to the total liquidity across all ticks. * Returned value cannot exceed type(uint128).max */ function liquidity() external view returns (uint128); /** * @notice Look up information about a specific tick in the pool * @dev This is a public structure, so the `return` natspec tags are omitted. * @param tick The tick to look up * @return liquidityTotal the total amount of position liquidity that uses the pool either as tick lower or * tick upper; * Returns liquidityDelta how much liquidity changes when the pool price crosses the tick; * Returns outerFeeGrowth0Token the fee growth on the other side of the tick from the current tick in token0; * Returns outerFeeGrowth1Token the fee growth on the other side of the tick from the current tick in token1; * Returns outerTickCumulative the cumulative tick value on the other side of the tick from the current tick; * Returns outerSecondsPerLiquidity the seconds spent per liquidity on the other side of the tick from the current tick; * Returns outerSecondsSpent the seconds spent on the other side of the tick from the current tick; * Returns initialized Set to true if the tick is initialized, i.e. liquidityTotal is greater than 0 * otherwise equal to false. Outside values can only be used if the tick is initialized. * In addition, these values are only relative and must be used only in comparison to previous snapshots for * a specific position. */ function ticks(int24 tick) external view returns ( uint128 liquidityTotal, int128 liquidityDelta, uint256 outerFeeGrowth0Token, uint256 outerFeeGrowth1Token, int56 outerTickCumulative, uint160 outerSecondsPerLiquidity, uint32 outerSecondsSpent, bool initialized ); /** @notice Returns 256 packed tick initialized boolean values. See TickTable for more information */ function tickTable(int16 wordPosition) external view returns (uint256); /** * @notice Returns the information about a position by the position's key * @dev This is a public mapping of structures, so the `return` natspec tags are omitted. * @param key The position's key is a hash of a preimage composed by the owner, bottomTick and topTick * @return liquidityAmount The amount of liquidity in the position; * Returns lastLiquidityAddTimestamp Timestamp of last adding of liquidity; * Returns innerFeeGrowth0Token Fee growth of token0 inside the tick range as of the last mint/burn/poke; * Returns innerFeeGrowth1Token Fee growth of token1 inside the tick range as of the last mint/burn/poke; * Returns fees0 The computed amount of token0 owed to the position as of the last mint/burn/poke; * Returns fees1 The computed amount of token1 owed to the position as of the last mint/burn/poke */ function positions(bytes32 key) external view returns ( uint128 liquidityAmount, uint32 lastLiquidityAddTimestamp, uint256 innerFeeGrowth0Token, uint256 innerFeeGrowth1Token, uint128 fees0, uint128 fees1 ); /** * @notice Returns data about a specific timepoint index * @param index The element of the timepoints array to fetch * @dev You most likely want to use #getTimepoints() instead of this method to get an timepoint as of some amount of time * ago, rather than at a specific index in the array. * This is a public mapping of structures, so the `return` natspec tags are omitted. * @return initialized whether the timepoint has been initialized and the values are safe to use; * Returns blockTimestamp The timestamp of the timepoint; * Returns tickCumulative the tick multiplied by seconds elapsed for the life of the pool as of the timepoint timestamp; * Returns secondsPerLiquidityCumulative the seconds per in range liquidity for the life of the pool as of the timepoint timestamp; * Returns volatilityCumulative Cumulative standard deviation for the life of the pool as of the timepoint timestamp; * Returns averageTick Time-weighted average tick; * Returns volumePerLiquidityCumulative Cumulative swap volume per liquidity for the life of the pool as of the timepoint timestamp; */ function timepoints(uint256 index) external view returns ( bool initialized, uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulative, uint88 volatilityCumulative, int24 averageTick, uint144 volumePerLiquidityCumulative ); /** * @notice Returns the information about active incentive * @dev if there is no active incentive at the moment, virtualPool,endTimestamp,startTimestamp would be equal to 0 * @return virtualPool The address of a virtual pool associated with the current active incentive */ function activeIncentive() external view returns (address virtualPool); /** * @notice Returns the lock time for added liquidity */ function liquidityCooldown() external view returns (uint32 cooldownInSeconds); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /** * @title Pool state that is not stored * @notice Contains view functions to provide information about the pool that is computed rather than stored on the * blockchain. The functions here may have variable gas costs. * @dev Credit to Uniswap Labs under GPL-2.0-or-later license: * https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces */ interface IAlgebraPoolDerivedState { /** * @notice Returns the cumulative tick and liquidity as of each timestamp `secondsAgo` from the current block timestamp * @dev To get a time weighted average tick or liquidity-in-range, you must call this with two values, one representing * the beginning of the period and another for the end of the period. E.g., to get the last hour time-weighted average tick, * you must call it with secondsAgos = [3600, 0]. * @dev The time weighted average tick represents the geometric time weighted average price of the pool, in * log base sqrt(1.0001) of token1 / token0. The TickMath library can be used to go from a tick value to a ratio. * @param secondsAgos From how long ago each cumulative tick and liquidity value should be returned * @return tickCumulatives Cumulative tick values as of each `secondsAgos` from the current block timestamp * @return secondsPerLiquidityCumulatives Cumulative seconds per liquidity-in-range value as of each `secondsAgos` * from the current block timestamp * @return volatilityCumulatives Cumulative standard deviation as of each `secondsAgos` * @return volumePerAvgLiquiditys Cumulative swap volume per liquidity as of each `secondsAgos` */ function getTimepoints(uint32[] calldata secondsAgos) external view returns ( int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulatives, uint112[] memory volatilityCumulatives, uint256[] memory volumePerAvgLiquiditys ); /** * @notice Returns a snapshot of the tick cumulative, seconds per liquidity and seconds inside a tick range * @dev Snapshots must only be compared to other snapshots, taken over a period for which a position existed. * I.e., snapshots cannot be compared if a position is not held for the entire period between when the first * snapshot is taken and the second snapshot is taken. * @param bottomTick The lower tick of the range * @param topTick The upper tick of the range * @return innerTickCumulative The snapshot of the tick accumulator for the range * @return innerSecondsSpentPerLiquidity The snapshot of seconds per liquidity for the range * @return innerSecondsSpent The snapshot of the number of seconds during which the price was in this range */ function getInnerCumulatives(int24 bottomTick, int24 topTick) external view returns ( int56 innerTickCumulative, uint160 innerSecondsSpentPerLiquidity, uint32 innerSecondsSpent ); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Permissionless pool actions /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces interface IAlgebraPoolActions { /** * @notice Sets the initial price for the pool * @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value * @param price the initial sqrt price of the pool as a Q64.96 */ function initialize(uint160 price) external; /** * @notice Adds liquidity for the given recipient/bottomTick/topTick position * @dev The caller of this method receives a callback in the form of IAlgebraMintCallback# AlgebraMintCallback * in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends * on bottomTick, topTick, the amount of liquidity, and the current price. * @param sender The address which will receive potential surplus of paid tokens * @param recipient The address for which the liquidity will be created * @param bottomTick The lower tick of the position in which to add liquidity * @param topTick The upper tick of the position in which to add liquidity * @param amount The desired amount of liquidity to mint * @param data Any data that should be passed through to the callback * @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback * @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback * @return liquidityActual The actual minted amount of liquidity */ function mint( address sender, address recipient, int24 bottomTick, int24 topTick, uint128 amount, bytes calldata data ) external returns ( uint256 amount0, uint256 amount1, uint128 liquidityActual ); /** * @notice Collects tokens owed to a position * @dev Does not recompute fees earned, which must be done either via mint or burn of any amount of liquidity. * Collect must be called by the position owner. To withdraw only token0 or only token1, amount0Requested or * amount1Requested may be set to zero. To withdraw all tokens owed, caller may pass any value greater than the * actual tokens owed, e.g. type(uint128).max. Tokens owed may be from accumulated swap fees or burned liquidity. * @param recipient The address which should receive the fees collected * @param bottomTick The lower tick of the position for which to collect fees * @param topTick The upper tick of the position for which to collect fees * @param amount0Requested How much token0 should be withdrawn from the fees owed * @param amount1Requested How much token1 should be withdrawn from the fees owed * @return amount0 The amount of fees collected in token0 * @return amount1 The amount of fees collected in token1 */ function collect( address recipient, int24 bottomTick, int24 topTick, uint128 amount0Requested, uint128 amount1Requested ) external returns (uint128 amount0, uint128 amount1); /** * @notice Burn liquidity from the sender and account tokens owed for the liquidity to the position * @dev Can be used to trigger a recalculation of fees owed to a position by calling with an amount of 0 * @dev Fees must be collected separately via a call to #collect * @param bottomTick The lower tick of the position for which to burn liquidity * @param topTick The upper tick of the position for which to burn liquidity * @param amount How much liquidity to burn * @return amount0 The amount of token0 sent to the recipient * @return amount1 The amount of token1 sent to the recipient */ function burn( int24 bottomTick, int24 topTick, uint128 amount ) external returns (uint256 amount0, uint256 amount1); /** * @notice Swap token0 for token1, or token1 for token0 * @dev The caller of this method receives a callback in the form of IAlgebraSwapCallback# AlgebraSwapCallback * @param recipient The address to receive the output of the swap * @param zeroToOne The direction of the swap, true for token0 to token1, false for token1 to token0 * @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative) * @param limitSqrtPrice The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this * value after the swap. If one for zero, the price cannot be greater than this value after the swap * @param data Any data to be passed through to the callback. If using the Router it should contain * SwapRouter#SwapCallbackData * @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive * @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive */ function swap( address recipient, bool zeroToOne, int256 amountSpecified, uint160 limitSqrtPrice, bytes calldata data ) external returns (int256 amount0, int256 amount1); /** * @notice Swap token0 for token1, or token1 for token0 (tokens that have fee on transfer) * @dev The caller of this method receives a callback in the form of I AlgebraSwapCallback# AlgebraSwapCallback * @param sender The address called this function (Comes from the Router) * @param recipient The address to receive the output of the swap * @param zeroToOne The direction of the swap, true for token0 to token1, false for token1 to token0 * @param amountSpecified The amount of the swap, which implicitly configures the swap as exact input (positive), or exact output (negative) * @param limitSqrtPrice The Q64.96 sqrt price limit. If zero for one, the price cannot be less than this * value after the swap. If one for zero, the price cannot be greater than this value after the swap * @param data Any data to be passed through to the callback. If using the Router it should contain * SwapRouter#SwapCallbackData * @return amount0 The delta of the balance of token0 of the pool, exact when negative, minimum when positive * @return amount1 The delta of the balance of token1 of the pool, exact when negative, minimum when positive */ function swapSupportingFeeOnInputTokens( address sender, address recipient, bool zeroToOne, int256 amountSpecified, uint160 limitSqrtPrice, bytes calldata data ) external returns (int256 amount0, int256 amount1); /** * @notice Receive token0 and/or token1 and pay it back, plus a fee, in the callback * @dev The caller of this method receives a callback in the form of IAlgebraFlashCallback# AlgebraFlashCallback * @dev All excess tokens paid in the callback are distributed to liquidity providers as an additional fee. So this method can be used * to donate underlying tokens to currently in-range liquidity providers by calling with 0 amount{0,1} and sending * the donation amount(s) from the callback * @param recipient The address which will receive the token0 and token1 amounts * @param amount0 The amount of token0 to send * @param amount1 The amount of token1 to send * @param data Any data to be passed through to the callback */ function flash( address recipient, uint256 amount0, uint256 amount1, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /** * @title Permissioned pool actions * @notice Contains pool methods that may only be called by the factory owner or tokenomics * @dev Credit to Uniswap Labs under GPL-2.0-or-later license: * https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces */ interface IAlgebraPoolPermissionedActions { /** * @notice Set the community's % share of the fees. Cannot exceed 25% (250) * @param communityFee0 new community fee percent for token0 of the pool in thousandths (1e-3) * @param communityFee1 new community fee percent for token1 of the pool in thousandths (1e-3) */ function setCommunityFee(uint8 communityFee0, uint8 communityFee1) external; /** * @notice Sets an active incentive * @param virtualPoolAddress The address of a virtual pool associated with the incentive */ function setIncentive(address virtualPoolAddress) external; /** * @notice Sets new lock time for added liquidity * @param newLiquidityCooldown The time in seconds */ function setLiquidityCooldown(uint32 newLiquidityCooldown) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Events emitted by a pool /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license: /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces interface IAlgebraPoolEvents { /** * @notice Emitted exactly once by a pool when #initialize is first called on the pool * @dev Mint/Burn/Swap cannot be emitted by the pool before Initialize * @param price The initial sqrt price of the pool, as a Q64.96 * @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool */ event Initialize(uint160 price, int24 tick); /** * @notice Emitted when liquidity is minted for a given position * @param sender The address that minted the liquidity * @param owner The owner of the position and recipient of any minted liquidity * @param bottomTick The lower tick of the position * @param topTick The upper tick of the position * @param liquidityAmount The amount of liquidity minted to the position range * @param amount0 How much token0 was required for the minted liquidity * @param amount1 How much token1 was required for the minted liquidity */ event Mint( address sender, address indexed owner, int24 indexed bottomTick, int24 indexed topTick, uint128 liquidityAmount, uint256 amount0, uint256 amount1 ); /** * @notice Emitted when fees are collected by the owner of a position * @dev Collect events may be emitted with zero amount0 and amount1 when the caller chooses not to collect fees * @param owner The owner of the position for which fees are collected * @param recipient The address that received fees * @param bottomTick The lower tick of the position * @param topTick The upper tick of the position * @param amount0 The amount of token0 fees collected * @param amount1 The amount of token1 fees collected */ event Collect(address indexed owner, address recipient, int24 indexed bottomTick, int24 indexed topTick, uint128 amount0, uint128 amount1); /** * @notice Emitted when a position's liquidity is removed * @dev Does not withdraw any fees earned by the liquidity position, which must be withdrawn via #collect * @param owner The owner of the position for which liquidity is removed * @param bottomTick The lower tick of the position * @param topTick The upper tick of the position * @param liquidityAmount The amount of liquidity to remove * @param amount0 The amount of token0 withdrawn * @param amount1 The amount of token1 withdrawn */ event Burn(address indexed owner, int24 indexed bottomTick, int24 indexed topTick, uint128 liquidityAmount, uint256 amount0, uint256 amount1); /** * @notice Emitted by the pool for any swaps between token0 and token1 * @param sender The address that initiated the swap call, and that received the callback * @param recipient The address that received the output of the swap * @param amount0 The delta of the token0 balance of the pool * @param amount1 The delta of the token1 balance of the pool * @param price The sqrt(price) of the pool after the swap, as a Q64.96 * @param liquidity The liquidity of the pool after the swap * @param tick The log base 1.0001 of price of the pool after the swap */ event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 price, uint128 liquidity, int24 tick); /** * @notice Emitted by the pool for any flashes of token0/token1 * @param sender The address that initiated the swap call, and that received the callback * @param recipient The address that received the tokens from flash * @param amount0 The amount of token0 that was flashed * @param amount1 The amount of token1 that was flashed * @param paid0 The amount of token0 paid for the flash, which can exceed the amount0 plus the fee * @param paid1 The amount of token1 paid for the flash, which can exceed the amount1 plus the fee */ event Flash(address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1, uint256 paid0, uint256 paid1); /** * @notice Emitted when the community fee is changed by the pool * @param communityFee0New The updated value of the token0 community fee percent * @param communityFee1New The updated value of the token1 community fee percent */ event CommunityFee(uint8 communityFee0New, uint8 communityFee1New); /** * @notice Emitted when new activeIncentive is set * @param virtualPoolAddress The address of a virtual pool associated with the current active incentive */ event Incentive(address indexed virtualPoolAddress); /** * @notice Emitted when the fee changes * @param fee The value of the token fee */ event Fee(uint16 fee); /** * @notice Emitted when the LiquidityCooldown changes * @param liquidityCooldown The value of locktime for added liquidity */ event LiquidityCooldown(uint32 liquidityCooldown); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; pragma abicoder v2; import '../libraries/AdaptiveFee.sol'; interface IDataStorageOperator { event FeeConfiguration(AdaptiveFee.Configuration feeConfig); /** * @notice Returns data belonging to a certain timepoint * @param index The index of timepoint in the array * @dev There is more convenient function to fetch a timepoint: observe(). Which requires not an index but seconds * @return initialized Whether the timepoint has been initialized and the values are safe to use, * blockTimestamp The timestamp of the observation, * tickCumulative The tick multiplied by seconds elapsed for the life of the pool as of the timepoint timestamp, * secondsPerLiquidityCumulative The seconds per in range liquidity for the life of the pool as of the timepoint timestamp, * volatilityCumulative Cumulative standard deviation for the life of the pool as of the timepoint timestamp, * averageTick Time-weighted average tick, * volumePerLiquidityCumulative Cumulative swap volume per liquidity for the life of the pool as of the timepoint timestamp */ function timepoints(uint256 index) external view returns ( bool initialized, uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulative, uint88 volatilityCumulative, int24 averageTick, uint144 volumePerLiquidityCumulative ); /// @notice Initialize the dataStorage array by writing the first slot. Called once for the lifecycle of the timepoints array /// @param time The time of the dataStorage initialization, via block.timestamp truncated to uint32 /// @param tick Initial tick function initialize(uint32 time, int24 tick) external; /// @dev Reverts if an timepoint at or before the desired timepoint timestamp does not exist. /// 0 may be passed as `secondsAgo' to return the current cumulative values. /// If called with a timestamp falling between two timepoints, returns the counterfactual accumulator values /// at exactly the timestamp between the two timepoints. /// @param time The current block timestamp /// @param secondsAgo The amount of time to look back, in seconds, at which point to return an timepoint /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return tickCumulative The cumulative tick since the pool was first initialized, as of `secondsAgo` /// @return secondsPerLiquidityCumulative The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of `secondsAgo` /// @return volatilityCumulative The cumulative volatility value since the pool was first initialized, as of `secondsAgo` /// @return volumePerAvgLiquidity The cumulative volume per liquidity value since the pool was first initialized, as of `secondsAgo` function getSingleTimepoint( uint32 time, uint32 secondsAgo, int24 tick, uint16 index, uint128 liquidity ) external view returns ( int56 tickCumulative, uint160 secondsPerLiquidityCumulative, uint112 volatilityCumulative, uint256 volumePerAvgLiquidity ); /// @notice Returns the accumulator values as of each time seconds ago from the given time in the array of `secondsAgos` /// @dev Reverts if `secondsAgos` > oldest timepoint /// @param time The current block.timestamp /// @param secondsAgos Each amount of time to look back, in seconds, at which point to return an timepoint /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return tickCumulatives The cumulative tick since the pool was first initialized, as of each `secondsAgo` /// @return secondsPerLiquidityCumulatives The cumulative seconds / max(1, liquidity) since the pool was first initialized, as of each `secondsAgo` /// @return volatilityCumulatives The cumulative volatility values since the pool was first initialized, as of each `secondsAgo` /// @return volumePerAvgLiquiditys The cumulative volume per liquidity values since the pool was first initialized, as of each `secondsAgo` function getTimepoints( uint32 time, uint32[] memory secondsAgos, int24 tick, uint16 index, uint128 liquidity ) external view returns ( int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulatives, uint112[] memory volatilityCumulatives, uint256[] memory volumePerAvgLiquiditys ); /// @notice Returns average volatility in the range from time-WINDOW to time /// @param time The current block.timestamp /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return TWVolatilityAverage The average volatility in the recent range /// @return TWVolumePerLiqAverage The average volume per liquidity in the recent range function getAverages( uint32 time, int24 tick, uint16 index, uint128 liquidity ) external view returns (uint112 TWVolatilityAverage, uint256 TWVolumePerLiqAverage); /// @notice Writes an dataStorage timepoint to the array /// @dev Writable at most once per block. Index represents the most recently written element. index must be tracked externally. /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param blockTimestamp The timestamp of the new timepoint /// @param tick The active tick at the time of the new timepoint /// @param liquidity The total in-range liquidity at the time of the new timepoint /// @param volumePerLiquidity The gmean(volumes)/liquidity at the time of the new timepoint /// @return indexUpdated The new index of the most recently written element in the dataStorage array function write( uint16 index, uint32 blockTimestamp, int24 tick, uint128 liquidity, uint128 volumePerLiquidity ) external returns (uint16 indexUpdated); /// @notice Changes fee configuration for the pool function changeFeeConfiguration(AdaptiveFee.Configuration calldata feeConfig) external; /// @notice Calculates gmean(volume/liquidity) for block /// @param liquidity The current in-range pool liquidity /// @param amount0 Total amount of swapped token0 /// @param amount1 Total amount of swapped token1 /// @return volumePerLiquidity gmean(volume/liquidity) capped by 100000 << 64 function calculateVolumePerLiquidity( uint128 liquidity, int256 amount0, int256 amount1 ) external pure returns (uint128 volumePerLiquidity); /// @return windowLength Length of window used to calculate averages function window() external view returns (uint32 windowLength); /// @notice Calculates fee based on combination of sigmoids /// @param time The current block.timestamp /// @param tick The current tick /// @param index The index of the timepoint that was most recently written to the timepoints array /// @param liquidity The current in-range pool liquidity /// @return fee The fee in hundredths of a bip, i.e. 1e-6 function getFee( uint32 time, int24 tick, uint16 index, uint128 liquidity ) external view returns (uint16 fee); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity =0.7.6; import './Constants.sol'; /// @title AdaptiveFee /// @notice Calculates fee based on combination of sigmoids library AdaptiveFee { // alpha1 + alpha2 + baseFee must be <= type(uint16).max struct Configuration { uint16 alpha1; // max value of the first sigmoid uint16 alpha2; // max value of the second sigmoid uint32 beta1; // shift along the x-axis for the first sigmoid uint32 beta2; // shift along the x-axis for the second sigmoid uint16 gamma1; // horizontal stretch factor for the first sigmoid uint16 gamma2; // horizontal stretch factor for the second sigmoid uint32 volumeBeta; // shift along the x-axis for the outer volume-sigmoid uint16 volumeGamma; // horizontal stretch factor the outer volume-sigmoid uint16 baseFee; // minimum possible fee } /// @notice Calculates fee based on formula: /// baseFee + sigmoidVolume(sigmoid1(volatility, volumePerLiquidity) + sigmoid2(volatility, volumePerLiquidity)) /// maximum value capped by baseFee + alpha1 + alpha2 function getFee( uint88 volatility, uint256 volumePerLiquidity, Configuration memory config ) internal pure returns (uint16 fee) { uint256 sumOfSigmoids = sigmoid(volatility, config.gamma1, config.alpha1, config.beta1) + sigmoid(volatility, config.gamma2, config.alpha2, config.beta2); if (sumOfSigmoids > type(uint16).max) { // should be impossible, just in case sumOfSigmoids = type(uint16).max; } return uint16(config.baseFee + sigmoid(volumePerLiquidity, config.volumeGamma, uint16(sumOfSigmoids), config.volumeBeta)); // safe since alpha1 + alpha2 + baseFee _must_ be <= type(uint16).max } /// @notice calculates α / (1 + e^( (β-x) / γ)) /// that is a sigmoid with a maximum value of α, x-shifted by β, and stretched by γ /// @dev returns uint256 for fuzzy testing. Guaranteed that the result is not greater than alpha function sigmoid( uint256 x, uint16 g, uint16 alpha, uint256 beta ) internal pure returns (uint256 res) { if (x > beta) { x = x - beta; if (x >= 6 * uint256(g)) return alpha; // so x < 19 bits uint256 g8 = uint256(g)**8; // < 128 bits (8*16) uint256 ex = exp(x, g, g8); // < 155 bits res = (alpha * ex) / (g8 + ex); // in worst case: (16 + 155 bits) / 155 bits // so res <= alpha } else { x = beta - x; if (x >= 6 * uint256(g)) return 0; // so x < 19 bits uint256 g8 = uint256(g)**8; // < 128 bits (8*16) uint256 ex = g8 + exp(x, g, g8); // < 156 bits res = (alpha * g8) / ex; // in worst case: (16 + 128 bits) / 156 bits // g8 <= ex, so res <= alpha } } /// @notice calculates e^(x/g) * g^8 in a series, since (around zero): /// e^x = 1 + x + x^2/2 + ... + x^n/n! + ... /// e^(x/g) = 1 + x/g + x^2/(2*g^2) + ... + x^(n)/(g^n * n!) + ... function exp( uint256 x, uint16 g, uint256 gHighestDegree ) internal pure returns (uint256 res) { // calculating: // g**8 + x * g**7 + (x**2 * g**6) / 2 + (x**3 * g**5) / 6 + (x**4 * g**4) / 24 + (x**5 * g**3) / 120 + (x**6 * g^2) / 720 + x**7 * g / 5040 + x**8 / 40320 // x**8 < 152 bits (19*8) and g**8 < 128 bits (8*16) // so each summand < 152 bits and res < 155 bits uint256 xLowestDegree = x; res = gHighestDegree; // g**8 gHighestDegree /= g; // g**7 res += xLowestDegree * gHighestDegree; gHighestDegree /= g; // g**6 xLowestDegree *= x; // x**2 res += (xLowestDegree * gHighestDegree) / 2; gHighestDegree /= g; // g**5 xLowestDegree *= x; // x**3 res += (xLowestDegree * gHighestDegree) / 6; gHighestDegree /= g; // g**4 xLowestDegree *= x; // x**4 res += (xLowestDegree * gHighestDegree) / 24; gHighestDegree /= g; // g**3 xLowestDegree *= x; // x**5 res += (xLowestDegree * gHighestDegree) / 120; gHighestDegree /= g; // g**2 xLowestDegree *= x; // x**6 res += (xLowestDegree * gHighestDegree) / 720; xLowestDegree *= x; // x**7 res += (xLowestDegree * g) / 5040 + (xLowestDegree * x) / (40320); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.7.6; library Constants { uint8 internal constant RESOLUTION = 96; uint256 internal constant Q96 = 0x1000000000000000000000000; uint256 internal constant Q128 = 0x100000000000000000000000000000000; // fee value in hundredths of a bip, i.e. 1e-6 uint16 internal constant BASE_FEE = 100; int24 internal constant TICK_SPACING = 60; // max(uint128) / ( (MAX_TICK - MIN_TICK) / TICK_SPACING ) uint128 internal constant MAX_LIQUIDITY_PER_TICK = 11505743598341114571880798222544994; uint32 internal constant MAX_LIQUIDITY_COOLDOWN = 1 days; uint8 internal constant MAX_COMMUNITY_FEE = 250; uint256 internal constant COMMUNITY_FEE_DENOMINATOR = 1000; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.4.0; /// @title FixedPoint96 /// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format) /// @dev Used in SqrtPriceMath.sol library FixedPoint96 { uint8 internal constant RESOLUTION = 96; uint256 internal constant Q96 = 0x1000000000000000000000000; }
{ "optimizer": { "enabled": true, "runs": 800 }, "metadata": { "bytecodeHash": "none" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"int24","name":"tick","type":"int24"},{"indexed":false,"internalType":"uint256","name":"totalAmount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalAmount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeAmount1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"Rebalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"newFee","type":"uint8"}],"name":"SetFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"fee","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"fees0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fees1","type":"uint256"}],"name":"ZeroBurn","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"uint256[2]","name":"inMin","type":"uint256[2]"}],"name":"addLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"algebraMintCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseLower","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseUpper","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[4]","name":"inMin","type":"uint256[4]"}],"name":"compound","outputs":[{"internalType":"uint128","name":"baseToken0Owed","type":"uint128"},{"internalType":"uint128","name":"baseToken1Owed","type":"uint128"},{"internalType":"uint128","name":"limitToken0Owed","type":"uint128"},{"internalType":"uint128","name":"limitToken1Owed","type":"uint128"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentTick","outputs":[{"internalType":"int24","name":"tick","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"deposit0","type":"uint256"},{"internalType":"uint256","name":"deposit1","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[4]","name":"inMin","type":"uint256[4]"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit0Max","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deposit1Max","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"directDeposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBasePosition","outputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLimitPosition","outputs":[{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalAmounts","outputs":[{"internalType":"uint256","name":"total0","type":"uint256"},{"internalType":"uint256","name":"total1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"limitLower","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"limitUpper","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract IAlgebraPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"shares","type":"uint128"},{"internalType":"uint256[2]","name":"amountMin","type":"uint256[2]"}],"name":"pullLiquidity","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int24","name":"_baseLower","type":"int24"},{"internalType":"int24","name":"_baseUpper","type":"int24"},{"internalType":"int24","name":"_limitLower","type":"int24"},{"internalType":"int24","name":"_limitUpper","type":"int24"},{"internalType":"address","name":"_feeRecipient","type":"address"},{"internalType":"uint256[4]","name":"inMin","type":"uint256[4]"},{"internalType":"uint256[4]","name":"outMin","type":"uint256[4]"}],"name":"rebalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeWhitelisted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"newFee","type":"uint8"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tickSpacing","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleDirectDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whitelistedAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[4]","name":"minAmounts","type":"uint256[4]"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101406040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c961012052600a805460ff60a01b1916600760a01b1790553480156200004a57600080fd5b5060405162004d8b38038062004d8b833981810160405260808110156200007057600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200009c57600080fd5b908301906020820185811115620000b257600080fd5b8251640100000000811182820188101715620000cd57600080fd5b82525081516020918201929091019080838360005b83811015620000fc578181015183820152602001620000e2565b50505050905090810190601f1680156200012a5780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200014e57600080fd5b9083019060208201858111156200016457600080fd5b82516401000000008111828201881017156200017f57600080fd5b82525081516020918201929091019080838360005b83811015620001ae57818101518382015260200162000194565b50505050905090810190601f168015620001dc5780820380516001836020036101000a031916815260200191505b506040525050508180604051806040016040528060018152602001603160f81b815250848481600390805190602001906200021992919062000575565b5080516200022f90600490602084019062000575565b50506005805460ff1916601217905550815160208084019190912082519183019190912060c082905260e08190527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620002886200050d565b60a0526200029881848462000511565b60805261010052505060016007555050506001600160a01b038416620002bd57600080fd5b6001600160a01b038316620002d157600080fd5b600880546001600160a01b0319166001600160a01b03868116919091179182905560408051630dfe168160e01b815290519290911691630dfe168191600480820192602092909190829003018186803b1580156200032e57600080fd5b505afa15801562000343573d6000803e3d6000fd5b505050506040513d60208110156200035a57600080fd5b5051600980546001600160a01b0319166001600160a01b039283161790556008546040805163d21220a760e01b81529051919092169163d21220a7916004808301926020929190829003018186803b158015620003b657600080fd5b505afa158015620003cb573d6000803e3d6000fd5b505050506040513d6020811015620003e257600080fd5b5051600a80546001600160a01b0319166001600160a01b03928316179055600954166200040e57600080fd5b600a546001600160a01b03166200042457600080fd5b600860009054906101000a90046001600160a01b03166001600160a01b031663d0c93a7c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156200047357600080fd5b505afa15801562000488573d6000803e3d6000fd5b505050506040513d60208110156200049f57600080fd5b5051600a805460029290920b62ffffff16600160a81b0262ffffff60a81b199092169190911790555050600b80546001600160a01b03909216660100000000000002600160301b600160d01b0319909216919091179055506000600e55600019600c819055600d5562000621565b4690565b6000838383620005206200050d565b3060405160200180868152602001858152602001848152602001838152602001826001600160a01b03168152602001955050505050506040516020818303038152906040528051906020012090509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620005ad5760008555620005f8565b82601f10620005c857805160ff1916838001178555620005f8565b82800160010185558215620005f8579182015b82811115620005f8578251825591602001919060010190620005db565b50620006069291506200060a565b5090565b5b808211156200060657600081556001016200060b565b60805160a05160c05160e05161010051610120516147206200066b6000398061253f525080612ab8525080612afa525080612ad9525080612a5f525080612a8f52506147206000f3fe608060405234801561001057600080fd5b50600436106103155760003560e01c806385919c5d116101a7578063b1a3d533116100ee578063d2eabcfc11610097578063ddca3f4311610071578063ddca3f4314610a68578063f2fde38b14610a70578063fa08274314610a9657610315565b8063d2eabcfc146109e1578063d505accf146109e9578063dd62ed3e14610a3a57610315565b8063cb122a09116100c8578063cb122a09146109b1578063d0c93a7c146109d1578063d21220a7146109d957610315565b8063b1a3d53314610999578063c4a7761e146109a1578063c5241e29146109a957610315565b806395d89b4111610150578063a85598721161012a578063a8559872146108fa578063a9059cbb14610965578063aaf5eb681461099157610315565b806395d89b4114610896578063a049de6b1461089e578063a457c2d7146108ce57610315565b80638da5cb5b116101815780638da5cb5b146107975780638e3c92e41461079f578063952356561461081057610315565b806385919c5d146106da57806386a2908114610787578063888a91341461078f57610315565b8063395093511161026b57806363e968361161021457806370a08231116101ee57806370a08231146106685780637ecebe001461068e578063854cff2f146106b457610315565b806363e96836146105f0578063648cab85146106585780636d90a39c1461066057610315565b80634d461fbb116102455780634d461fbb1461055a578063513ea8841461056257806351e87af7146105e857610315565b806339509351146104a85780633dd657c5146104d4578063469048401461055257610315565b806316f0115b116102cd5780632ab4d052116102a75780632ab4d0521461047a578063313ce567146104825780633644e515146104a057610315565b806316f0115b1461042257806318160ddd1461042a57806323b872dd1461044457610315565b8063095ea7b3116102fe578063095ea7b3146103b65780630dfe1681146103f65780630f35bcac1461041a57610315565b8063065e53601461031a57806306fdde0314610339575b600080fd5b610322610a9e565b6040805160029290920b8252519081900360200190f35b610341610b17565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561037b578181015183820152602001610363565b50505050905090810190601f1680156103a85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103e2600480360360408110156103cc57600080fd5b506001600160a01b038135169060200135610bae565b604080519115158252519081900360200190f35b6103fe610bcc565b604080516001600160a01b039092168252519081900360200190f35b610322610bdb565b6103fe610beb565b610432610bfa565b60408051918252519081900360200190f35b6103e26004803603606081101561045a57600080fd5b506001600160a01b03813581169160208101359091169060400135610c00565b610432610c88565b61048a610c8e565b6040805160ff9092168252519081900360200190f35b610432610c97565b6103e2600480360360408110156104be57600080fd5b506001600160a01b038135169060200135610ca6565b610550600480360360608110156104ea57600080fd5b81359160208101359181019060608101604082013564010000000081111561051157600080fd5b82018360208201111561052357600080fd5b8035906020019184600183028401116401000000008311171561054557600080fd5b509092509050610cf4565b005b6103fe610d8e565b610432610d9d565b6105b46004803603608081101561057857600080fd5b8101908080608001906004806020026040519081016040528092919082600460200280828437600092019190915250919450610da39350505050565b604080516001600160801b039586168152938516602085015291841683830152909216606082015290519081900360800190f35b610322610ffa565b610550600480360360c081101561060657600080fd5b6040805180820182528335600290810b946020810135820b9484820135946060830135949183019360c08401929160808501919083908390808284376000920191909152509194506110039350505050565b610432611090565b6103e2611096565b6104326004803603602081101561067e57600080fd5b50356001600160a01b03166110a6565b610432600480360360208110156106a457600080fd5b50356001600160a01b03166110c5565b610550600480360360208110156106ca57600080fd5b50356001600160a01b03166110e6565b61055060048036036101a08110156106f157600080fd5b60408051608081810183528435600290810b956020810135820b9594810135820b94606082013590920b936001600160a01b03848301351693928201926101208301919060a0840190600490839083908082843760009201919091525050604080516080818101909252929594938181019392509060049083908390808284376000920191909152509194506111689350505050565b6103fe61178d565b61032261179c565b6103fe6117ac565b61043260048036036101008110156107b657600080fd5b60408051608081810183528435946020810135946001600160a01b03948201358516946060830135169390820192610100830191908084019060049083908390808284376000920191909152509194506117c29350505050565b61087d600480360360a081101561082657600080fd5b6040805180820182528335600290810b946020810135820b946001600160801b0385830135169490820193919260a0840192916060850191908390839080828437600092019190915250919450611c009350505050565b6040805192835260208301919091528051918290030190f35b610341611c98565b6108a6611cf9565b604080516001600160801b039094168452602084019290925282820152519081900360600190f35b6103e2600480360360408110156108e457600080fd5b506001600160a01b038135169060200135611d7f565b61087d600480360360e081101561091057600080fd5b60408051608081810183528435946001600160a01b036020820135811695948201351693810192909160e08301919060608401906004908390839080828437600092019190915250919450611de79350505050565b6103e26004803603604081101561097b57600080fd5b506001600160a01b038135169060200135612189565b61043261219d565b6105506121b0565b61087d612224565b610550612334565b610550600480360360208110156109c757600080fd5b503560ff166123a6565b610322612455565b6103fe612465565b6108a6612474565b610550600480360360e08110156109ff57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c001356124d0565b61043260048036036040811015610a5057600080fd5b506001600160a01b0381358116916020013516612687565b61048a6126b2565b61055060048036036020811015610a8657600080fd5b50356001600160a01b03166126c2565b610322612769565b600854604080516339db007960e21b815290516000926001600160a01b03169163e76c01e49160048083019260e0929190829003018186803b158015610ae357600080fd5b505afa158015610af7573d6000803e3d6000fd5b505050506040513d60e0811015610b0d57600080fd5b5060200151919050565b60038054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ba35780601f10610b7857610100808354040283529160200191610ba3565b820191906000526020600020905b815481529060010190602001808311610b8657829003601f168201915b505050505090505b90565b6000610bc2610bbb612779565b848461277d565b5060015b92915050565b6009546001600160a01b031681565b600b546301000000900460020b81565b6008546001600160a01b031681565b60025490565b6000610c0d848484612869565b610c7d84610c19612779565b610c7885604051806060016040528060288152602001614633602891396001600160a01b038a16600090815260016020526040812090610c57612779565b6001600160a01b0316815260208101919091526040016000205491906129c4565b61277d565b5060015b9392505050565b600e5481565b60055460ff1690565b6000610ca1612a5b565b905090565b6000610bc2610cb3612779565b84610c788560016000610cc4612779565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490612b25565b6008546001600160a01b03163314610d0b57600080fd5b601054600160a81b900460ff161515600114610d2657600080fd5b601080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690558315610d6b57600954610d6b906001600160a01b03163386612b7f565b8215610d8857600a54610d88906001600160a01b03163385612b7f565b50505050565b6010546001600160a01b031681565b600d5481565b600080600080600b60069054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b031614610e11576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b610e19612beb565b5050600a54600954604080516370a0823160e01b81523060048201529051600093610f2f93600160c01b8204600290810b94600160d81b909304900b926001600160a01b03909116916370a08231916024808301926020929190829003018186803b158015610e8757600080fd5b505afa158015610e9b573d6000803e3d6000fd5b505050506040513d6020811015610eb157600080fd5b5051600a54604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610efe57600080fd5b505afa158015610f12573d6000803e3d6000fd5b505050506040513d6020811015610f2857600080fd5b5051612c36565b600a548751919250610f6491600160c01b8204600290810b92600160d81b9004900b90849030908b60015b6020020151612cdc565b600b54600954604080516370a0823160e01b81523060048201529051610fc793600281810b946301000000909204900b926001600160a01b03909116916370a0823191602480820192602092909190829003018186803b158015610e8757600080fd5b600b546040880151919250610ff291600282810b9263010000009004900b90849030908b6003610f5a565b509193509193565b600b5460020b81565b600b54600160301b90046001600160a01b03163314611056576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b6110608585612ec0565b50600061106f86868686612c36565b9050611088868683308660006020020151876001610f5a565b505050505050565b600c5481565b601054600160a01b900460ff1681565b6001600160a01b0381166000908152602081905260409020545b919050565b6001600160a01b0381166000908152600660205260408120610bc690613237565b600b54600160301b90046001600160a01b03163314611139576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b600f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600260075414156111c0576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600755600b54600160301b90046001600160a01b03163314611218576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b8560020b8760020b12801561124a5750600a54600160a81b9004600290810b810b9088900b8161124457fe5b0760020b155b80156112735750600a54600160a81b9004600290810b810b9087900b8161126d57fe5b0760020b155b61127c57600080fd5b8360020b8560020b1280156112ae5750600a54600160a81b9004600290810b810b9086900b816112a857fe5b0760020b155b80156112d75750600a54600160a81b9004600290810b810b9085900b816112d157fe5b0760020b155b6112e057600080fd5b8560020b8460020b1415806112fb57508660020b8560020b14155b61130457600080fd5b6001600160a01b03831661131757600080fd5b6010805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038516179055611347612beb565b5050600a546000908190819061137290600160c01b8104600290810b91600160d81b9004900b61323b565b600b549295506001600160801b039182169450169150600090819081906113a790600281810b9163010000009004900b61323b565b600a549295506001600160801b0391821694501691506113f190600160c01b8104600290810b91600160d81b9004900b883060018c600060200201518d60015b60200201516132fd565b5050600b5461142190600281810b9163010000009004810b90869030906001908d905b60200201518d60036113e7565b50507fbc4c20ad04f161d631d9ce94d27659391196415aa3c42f6a71c62e905ece782d61144c610a9e565b600954604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561149757600080fd5b505afa1580156114ab573d6000803e3d6000fd5b505050506040513d60208110156114c157600080fd5b5051600a54604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561150e57600080fd5b505afa158015611522573d6000803e3d6000fd5b505050506040513d602081101561153857600080fd5b5051611544868a612b25565b61154e868a612b25565b611556610bfa565b6040805160029790970b87526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190a18c600a60186101000a81548162ffffff021916908360020b62ffffff1602179055508b600a601b6101000a81548162ffffff021916908360020b62ffffff160217905550611656600a60189054906101000a900460020b600a601b9054906101000a900460020b600960009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610e8757600080fd5b600a54895191975061168591600160c01b8204600290810b92600160d81b9004900b90899030908d6001610f5a565b8a600b60006101000a81548162ffffff021916908360020b62ffffff16021790555089600b60036101000a81548162ffffff021916908360020b62ffffff16021790555061174e600b60009054906101000a900460020b600b60039054906101000a900460020b600960009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610e8757600080fd5b600b5460408a015191945061177991600282810b9263010000009004900b90869030908d6003610f5a565b505060016007555050505050505050505050565b600f546001600160a01b031681565b600a54600160d81b900460020b81565b600b54600160301b90046001600160a01b031681565b60006002600754141561181c576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026007558515158061182f5750600085115b61183857600080fd5b600c54861115801561184c5750600d548511155b61185557600080fd5b6001600160a01b0384161580159061187657506001600160a01b0384163014155b6118ac576040805162461bcd60e51b8152602060048201526002602482015261746f60f01b604482015290519081900360640190fd5b600f546001600160a01b031633146118f1576040805162461bcd60e51b815260206004820152600360248201526257484560e81b604482015290519081900360640190fd5b6118f9612beb565b5050600061190d611908610a9e565b61354b565b905060006119416119276001600160a01b0384168061387d565b6ec097ce7bc90715b34b9f1000000000600160c01b6138d6565b905060008061194e612224565b90925090506119806119796ec097ce7bc90715b34b9f10000000006119738d8761387d565b90613985565b8a90612b25565b945089156119a0576009546119a0906001600160a01b031688308d6139ec565b88156119be57600a546119be906001600160a01b031688308c6139ec565b60006119c8610bfa565b90508015611b4a5760006119ef6ec097ce7bc90715b34b9f1000000000611973868861387d565b9050611a086119fe8285612b25565b611973898561387d565b601054909750600160a01b900460ff1615611b4857600a54600954604080516370a0823160e01b81523060048201529051600093611a8993600160c01b8204600290810b94600160d81b909304900b926001600160a01b03909116916370a08231916024808301926020929190829003018186803b158015610e8757600080fd5b600a548a51919250611ab891600160c01b8204600290810b92600160d81b9004900b90849030908e6001610f5a565b600b54600954604080516370a0823160e01b81523060048201529051611b1b93600281810b946301000000909204900b926001600160a01b03909116916370a0823191602480820192602092909190829003018186803b158015610e8757600080fd5b600b5460408b0151919250611b4691600282810b9263010000009004900b90849030908e6003610f5a565b505b505b611b548987613a5b565b60408051878152602081018d90528082018c905290516001600160a01b03808c1692908b16917f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f69181900360600190a3600e541580611bb55750600e548111155b611bec576040805162461bcd60e51b81526020600482015260036024820152620dac2f60eb1b604482015290519081900360640190fd5b505060016007555091979650505050505050565b600b546000908190600160301b90046001600160a01b03163314611c58576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b611c628686612ec0565b50611c8b8686611c7c8989896001600160801b0316613b4b565b865130906000908960016113e7565b9097909650945050505050565b60048054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ba35780601f10610b7857610100808354040283529160200191610ba3565b600b5460009081908190819081908190611d2190600281810b9163010000009004900b61323b565b600b549295509093509150611d4590600281810b9163010000009004900b85613b8b565b9095509350611d5d856001600160801b038416612b25565b9450611d72846001600160801b038316612b25565b9350829550505050909192565b6000610bc2611d8c612779565b84610c78856040518060600160405280602581526020016146ef6025913960016000611db6612779565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906129c4565b60008060026007541415611e42576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260075585611e99576040805162461bcd60e51b815260206004820152600660248201527f7368617265730000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b038516611ed9576040805162461bcd60e51b8152602060048201526002602482015261746f60f01b604482015290519081900360640190fd5b611ee1612beb565b5050600a546000908190611f1f90600160c01b8104600290810b91600160d81b9004900b611f1082828d613b4b565b88518b906000908b60016113e7565b600b5491935091506000908190611f5590600281810b9163010000009004900b611f4a82828f613b4b565b8c60008c6002611414565b915091506000611ffe611f66610bfa565b6119738d600960009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fcc57600080fd5b505afa158015611fe0573d6000803e3d6000fd5b505050506040513d6020811015611ff657600080fd5b50519061387d565b9050600061207361200d610bfa565b6119738e600a60009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fcc57600080fd5b9050811561209257600954612092906001600160a01b03168c84612b7f565b80156120af57600a546120af906001600160a01b03168c83612b7f565b6120c3826120bd8887612b25565b90612b25565b97506120d3816120bd8786612b25565b96506001600160a01b038a163314612118576040805162461bcd60e51b815260206004820152600360248201526237bbb760e91b604482015290519081900360640190fd5b6121228a8d613c35565b604080518d8152602081018a905280820189905290516001600160a01b03808e1692908d16917febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f9181900360600190a3505050505050600160078190555094509492505050565b6000610bc2612196612779565b8484612869565b6ec097ce7bc90715b34b9f100000000081565b600b54600160301b90046001600160a01b03163314612203576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b6010805460ff60a01b198116600160a01b9182900460ff1615909102179055565b600080600080612232612474565b9250925050600080612242611cf9565b600954604080516370a0823160e01b815230600482015290519396509194506122d0935085926120bd9289926001600160a01b0316916370a0823191602480820192602092909190829003018186803b15801561229e57600080fd5b505afa1580156122b2573d6000803e3d6000fd5b505050506040513d60208110156122c857600080fd5b505190612b25565b600a54604080516370a0823160e01b8152306004820152905192985061232a9284926120bd9288926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561229e57600080fd5b9450505050509091565b600b54600160301b90046001600160a01b03163314612387576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b600f805473ffffffffffffffffffffffffffffffffffffffff19169055565b600b54600160301b90046001600160a01b031633146123f9576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b600a805460ff808416600160a01b90810260ff60a01b199093169290921792839055604080519290930416815290517f91f2ade82ab0e77bb6823899e6daddc07e3da0e3ad998577e7c09c2f38943c439181900360200190a150565b600a54600160a81b900460020b81565b600a546001600160a01b031681565b6000806000806000806124a5600a60189054906101000a900460020b600a601b9054906101000a900460020b61323b565b600a549295509093509150611d4590600160c01b8104600290810b91600160d81b9004900b85613b8b565b83421115612525576040805162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015290519081900360640190fd5b6001600160a01b03871660009081526006602052604081207f00000000000000000000000000000000000000000000000000000000000000009089908990899061256e90613237565b8960405160200180878152602001866001600160a01b03168152602001856001600160a01b03168152602001848152602001838152602001828152602001965050505050505060405160208183030381529060405280519060200120905060006125d782613d31565b905060006125e782878787613d7d565b9050896001600160a01b0316816001600160a01b03161461264f576040805162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015290519081900360640190fd5b6001600160a01b038a16600090815260066020526040902061267090613ef2565b61267b8a8a8a61277d565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600a54600160a01b900460ff1681565b600b54600160301b90046001600160a01b03163314612715576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b6001600160a01b03811661272857600080fd5b600b80546001600160a01b03909216600160301b027fffffffffffff0000000000000000000000000000000000000000ffffffffffff909216919091179055565b600a54600160c01b900460020b81565b3390565b6001600160a01b0383166127c25760405162461bcd60e51b81526004018080602001828103825260248152602001806146a16024913960400191505060405180910390fd5b6001600160a01b0382166128075760405162461bcd60e51b81526004018080602001828103825260228152602001806145606022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166128ae5760405162461bcd60e51b815260040180806020018281038252602581526020018061467c6025913960400191505060405180910390fd5b6001600160a01b0382166128f35760405162461bcd60e51b815260040180806020018281038252602381526020018061451b6023913960400191505060405180910390fd5b6128fe838383612be6565b61293b81604051806060016040528060268152602001614582602691396001600160a01b03861660009081526020819052604090205491906129c4565b6001600160a01b03808516600090815260208190526040808220939093559084168152205461296a9082612b25565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115612a535760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612a18578181015183820152602001612a00565b50505050905090810190601f168015612a455780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60007f0000000000000000000000000000000000000000000000000000000000000000612a86613efb565b1415612ab357507f0000000000000000000000000000000000000000000000000000000000000000610bab565b612b1e7f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000613eff565b9050610bab565b600082820183811015610c81576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b179052612be6908490613f61565b505050565b600a546000908190612c1290600160c01b8104600290810b91600160d81b9004900b612ec0565b600b54909250612c3090600281810b9163010000009004900b612ec0565b90509091565b600080600860009054906101000a90046001600160a01b03166001600160a01b031663e76c01e46040518163ffffffff1660e01b815260040160e06040518083038186803b158015612c8757600080fd5b505afa158015612c9b573d6000803e3d6000fd5b505050506040513d60e0811015612cb157600080fd5b50519050612cd281612cc28861354b565b612ccb8861354b565b8787614012565b9695505050505050565b6001600160801b03841615611088576001601060156101000a81548160ff021916908315150217905550600080600860009054906101000a90046001600160a01b03166001600160a01b031663aafe29c030308b8b8b8b60405160200180826001600160a01b031681526020019150506040516020818303038152906040526040518763ffffffff1660e01b815260040180876001600160a01b03168152602001866001600160a01b031681526020018560020b81526020018460020b8152602001836001600160801b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612de6578181015183820152602001612dce565b50505050905090810190601f168015612e135780820380516001836020036101000a031916815260200191505b50975050505050505050606060405180830381600087803b158015612e3757600080fd5b505af1158015612e4b573d6000803e3d6000fd5b505050506040513d6060811015612e6157600080fd5b5080516020909101519092509050838210801590612e7f5750828110155b612eb6576040805162461bcd60e51b815260206004820152600360248201526250534360e81b604482015290519081900360640190fd5b5050505050505050565b6000612ecc838361323b565b50909150506001600160801b03811615610bc6576008546040805163a34123a760e01b8152600286810b600483015285900b602482015260006044820181905282516001600160a01b039094169363a34123a7936064808501949193918390030190829087803b158015612f3f57600080fd5b505af1158015612f53573d6000803e3d6000fd5b505050506040513d6040811015612f6957600080fd5b5050600854604080516309e3d67b60e31b8152306004820152600286810b602483015285900b60448201526001600160801b03606482018190526084820152815160009384936001600160a01b0390911692634f1eb3d89260a4808301939282900301818787803b158015612fdd57600080fd5b505af1158015612ff1573d6000803e3d6000fd5b505050506040513d604081101561300757600080fd5b508051602091820151600a546040805160ff600160a01b9093049290921682526001600160801b039384169482018590529290911681830181905291519294509092507f4606b8a47eb284e8e80929101ece6ab5fe8d4f8735acc56bd0c92ca872f2cfe7919081900360600190a1600a54600090613090908490600160a01b900460ff16613985565b1180156131115750600954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156130e357600080fd5b505afa1580156130f7573d6000803e3d6000fd5b505050506040513d602081101561310d57600080fd5b5051115b1561315257601054600a54613152916001600160a01b03169061313f908590600160a01b900460ff16613985565b6009546001600160a01b03169190612b7f565b600a5460009061316d908390600160a01b900460ff16613985565b1180156131ee5750600a54604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156131c057600080fd5b505afa1580156131d4573d6000803e3d6000fd5b505050506040513d60208110156131ea57600080fd5b5051115b1561322f57601054600a5461322f916001600160a01b03169061321c908490600160a01b900460ff16613985565b600a546001600160a01b03169190612b7f565b505092915050565b5490565b600080600080600030905062ffffff861662ffffff88168260181b1760181b179150600860009054906101000a90046001600160a01b03166001600160a01b031663514ea4bf836040518263ffffffff1660e01b81526004018082815260200191505060c06040518083038186803b1580156132b657600080fd5b505afa1580156132ca573d6000803e3d6000fd5b505050506040513d60c08110156132e057600080fd5b508051608082015160a09092015190999198509650945050505050565b6000806001600160801b0387161561353f576008546040805163a34123a760e01b815260028c810b60048301528b900b60248201526001600160801b038a166044820152815160009384936001600160a01b039091169263a34123a7926064808301939282900301818787803b15801561337657600080fd5b505af115801561338a573d6000803e3d6000fd5b505050506040513d60408110156133a057600080fd5b50805160209091015190925090508582108015906133be5750848110155b6133f5576040805162461bcd60e51b815260206004820152600360248201526250534360e81b604482015290519081900360640190fd5b60008761340a57613405836140ca565b613413565b6001600160801b035b905060008861342a57613425836140ca565b613433565b6001600160801b035b90506000826001600160801b0316118061345657506000816001600160801b0316115b1561353a57600860009054906101000a90046001600160a01b03166001600160a01b0316634f1eb3d88b8f8f86866040518663ffffffff1660e01b815260040180866001600160a01b031681526020018560020b81526020018460020b8152602001836001600160801b03168152602001826001600160801b03168152602001955050505050506040805180830381600087803b1580156134f657600080fd5b505af115801561350a573d6000803e3d6000fd5b505050506040513d604081101561352057600080fd5b5080516020909101516001600160801b0391821697501694505b505050505b97509795505050505050565b6000600282810b60171d90818418829003900b620d89e881111561359a576040805162461bcd60e51b81526020600482015260016024820152601560fa1b604482015290519081900360640190fd5b6000600182166135bb577001000000000000000000000000000000006135cd565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615613601576ffff97272373d413259a46990580e213a0260801c5b6004821615613620576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b600882161561363f576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b601082161561365e576fffcb9843d60f6159c9db58835c9266440260801c5b602082161561367d576fff973b41fa98c081472e6896dfb254c00260801c5b604082161561369c576fff2ea16466c96a3843ec78b326b528610260801c5b60808216156136bb576ffe5dee046a99a2a811c461f1969c30530260801c5b6101008216156136db576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b6102008216156136fb576ff987a7253ac413176f2b074cf7815e540260801c5b61040082161561371b576ff3392b0822b70005940c7a398e4b70f30260801c5b61080082161561373b576fe7159475a2c29b7443b29c7fa6e889d90260801c5b61100082161561375b576fd097f3bdfd2022b8845ad8f792aa58250260801c5b61200082161561377b576fa9f746462d870fdf8a65dc1f90e061e50260801c5b61400082161561379b576f70d869a156d2a1b890bb3df62baf32f70260801c5b6180008216156137bb576f31be135f97d08fd981231505542fcfa60260801c5b620100008216156137dc576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b620200008216156137fc576e5d6af8dedb81196699c329225ee6040260801c5b6204000082161561381b576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615613838576b048a170391f7dc42444e8fa20260801c5b60008560020b131561385357806000198161384f57fe5b0490505b64010000000081061561386757600161386a565b60005b60ff16602082901c019350505050919050565b60008261388c57506000610bc6565b8282028284828161389957fe5b0414610c815760405162461bcd60e51b81526004018080602001828103825260218152602001806146126021913960400191505060405180910390fd5b600080806000198587098686029250828110908390030390508061390c576000841161390157600080fd5b508290049050610c81565b80841161391857600080fd5b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b60008082116139db576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b8183816139e457fe5b049392505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b179052610d88908590613f61565b6001600160a01b038216613ab6576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b613ac260008383612be6565b600254613acf9082612b25565b6002556001600160a01b038216600090815260208190526040902054613af59082612b25565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600080613b58858561323b565b50509050613b82613b7d613b6a610bfa565b6119736001600160801b0385168761387d565b6140ca565b95945050505050565b6000806000600860009054906101000a90046001600160a01b03166001600160a01b031663e76c01e46040518163ffffffff1660e01b815260040160e06040518083038186803b158015613bde57600080fd5b505afa158015613bf2573d6000803e3d6000fd5b505050506040513d60e0811015613c0857600080fd5b50519050613c2881613c198861354b565b613c228861354b565b876140e1565b9250925050935093915050565b6001600160a01b038216613c7a5760405162461bcd60e51b815260040180806020018281038252602181526020018061465b6021913960400191505060405180910390fd5b613c8682600083612be6565b613cc38160405180606001604052806022815260200161453e602291396001600160a01b03851660009081526020819052604090205491906129c4565b6001600160a01b038316600090815260208190526040902055600254613ce9908261417d565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6000613d3b612a5b565b82604051602001808061190160f01b81525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050919050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115613dde5760405162461bcd60e51b81526004018080602001828103825260228152602001806145a86022913960400191505060405180910390fd5b8360ff16601b1480613df357508360ff16601c145b613e2e5760405162461bcd60e51b81526004018080602001828103825260228152602001806145f06022913960400191505060405180910390fd5b600060018686868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015613e8a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613b82576040805162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b80546001019055565b4690565b6000838383613f0c613efb565b3060405160200180868152602001858152602001848152602001838152602001826001600160a01b03168152602001955050505050506040516020818303038152906040528051906020012090509392505050565b6000613fb6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166141da9092919063ffffffff16565b805190915015612be657808060200190516020811015613fd557600080fd5b5051612be65760405162461bcd60e51b815260040180806020018281038252602a8152602001806146c5602a913960400191505060405180910390fd5b6000836001600160a01b0316856001600160a01b03161115614032579293925b846001600160a01b0316866001600160a01b03161161405d576140568585856141f1565b9050613b82565b836001600160a01b0316866001600160a01b031610156140bf5760006140848786866141f1565b90506000614093878986614254565b9050806001600160801b0316826001600160801b0316106140b457806140b6565b815b92505050613b82565b612cd2858584614254565b60006001600160801b038211156140dd57fe5b5090565b600080836001600160a01b0316856001600160a01b03161115614102579293925b846001600160a01b0316866001600160a01b03161161412d57614126858585614291565b9150614174565b836001600160a01b0316866001600160a01b0316101561416657614152868585614291565b915061415f8587856142fa565b9050614174565b6141718585856142fa565b90505b94509492505050565b6000828211156141d4576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60606141e9848460008561433d565b949350505050565b6000826001600160a01b0316846001600160a01b03161115614211579192915b6000614234856001600160a01b0316856001600160a01b0316600160601b6138d6565b9050613b8261424f84838888036001600160a01b03166138d6565b614498565b6000826001600160a01b0316846001600160a01b03161115614274579192915b6141e961424f83600160601b8787036001600160a01b03166138d6565b6000826001600160a01b0316846001600160a01b031611156142b1579192915b836001600160a01b03166142ea606060ff16846001600160801b0316901b8686036001600160a01b0316866001600160a01b03166138d6565b816142f157fe5b04949350505050565b6000826001600160a01b0316846001600160a01b0316111561431a579192915b6141e9826001600160801b03168585036001600160a01b0316600160601b6138d6565b60608247101561437e5760405162461bcd60e51b81526004018080602001828103825260268152602001806145ca6026913960400191505060405180910390fd5b614387856144ae565b6143d8576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106144165780518252601f1990920191602091820191016143f7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614478576040519150601f19603f3d011682016040523d82523d6000602084013e61447d565b606091505b509150915061448d8282866144b4565b979650505050505050565b806001600160801b03811681146110c057600080fd5b3b151590565b606083156144c3575081610c81565b8251156144d35782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315612a18578181015183820152602001612a0056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545434453413a20696e76616c6964207369676e6174757265202773272076616c7565416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c45434453413a20696e76616c6964207369676e6174757265202776272076616c7565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa164736f6c6343000706000a000000000000000000000000e7e0eb9f6bcccfe847fdf62a3628319a092f11a2000000000000000000000000ade38bd2e8d5a52e60047affe6e595bb5e61923a000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000961555344432d4441490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000961555344432d4441490000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103155760003560e01c806385919c5d116101a7578063b1a3d533116100ee578063d2eabcfc11610097578063ddca3f4311610071578063ddca3f4314610a68578063f2fde38b14610a70578063fa08274314610a9657610315565b8063d2eabcfc146109e1578063d505accf146109e9578063dd62ed3e14610a3a57610315565b8063cb122a09116100c8578063cb122a09146109b1578063d0c93a7c146109d1578063d21220a7146109d957610315565b8063b1a3d53314610999578063c4a7761e146109a1578063c5241e29146109a957610315565b806395d89b4111610150578063a85598721161012a578063a8559872146108fa578063a9059cbb14610965578063aaf5eb681461099157610315565b806395d89b4114610896578063a049de6b1461089e578063a457c2d7146108ce57610315565b80638da5cb5b116101815780638da5cb5b146107975780638e3c92e41461079f578063952356561461081057610315565b806385919c5d146106da57806386a2908114610787578063888a91341461078f57610315565b8063395093511161026b57806363e968361161021457806370a08231116101ee57806370a08231146106685780637ecebe001461068e578063854cff2f146106b457610315565b806363e96836146105f0578063648cab85146106585780636d90a39c1461066057610315565b80634d461fbb116102455780634d461fbb1461055a578063513ea8841461056257806351e87af7146105e857610315565b806339509351146104a85780633dd657c5146104d4578063469048401461055257610315565b806316f0115b116102cd5780632ab4d052116102a75780632ab4d0521461047a578063313ce567146104825780633644e515146104a057610315565b806316f0115b1461042257806318160ddd1461042a57806323b872dd1461044457610315565b8063095ea7b3116102fe578063095ea7b3146103b65780630dfe1681146103f65780630f35bcac1461041a57610315565b8063065e53601461031a57806306fdde0314610339575b600080fd5b610322610a9e565b6040805160029290920b8252519081900360200190f35b610341610b17565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561037b578181015183820152602001610363565b50505050905090810190601f1680156103a85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103e2600480360360408110156103cc57600080fd5b506001600160a01b038135169060200135610bae565b604080519115158252519081900360200190f35b6103fe610bcc565b604080516001600160a01b039092168252519081900360200190f35b610322610bdb565b6103fe610beb565b610432610bfa565b60408051918252519081900360200190f35b6103e26004803603606081101561045a57600080fd5b506001600160a01b03813581169160208101359091169060400135610c00565b610432610c88565b61048a610c8e565b6040805160ff9092168252519081900360200190f35b610432610c97565b6103e2600480360360408110156104be57600080fd5b506001600160a01b038135169060200135610ca6565b610550600480360360608110156104ea57600080fd5b81359160208101359181019060608101604082013564010000000081111561051157600080fd5b82018360208201111561052357600080fd5b8035906020019184600183028401116401000000008311171561054557600080fd5b509092509050610cf4565b005b6103fe610d8e565b610432610d9d565b6105b46004803603608081101561057857600080fd5b8101908080608001906004806020026040519081016040528092919082600460200280828437600092019190915250919450610da39350505050565b604080516001600160801b039586168152938516602085015291841683830152909216606082015290519081900360800190f35b610322610ffa565b610550600480360360c081101561060657600080fd5b6040805180820182528335600290810b946020810135820b9484820135946060830135949183019360c08401929160808501919083908390808284376000920191909152509194506110039350505050565b610432611090565b6103e2611096565b6104326004803603602081101561067e57600080fd5b50356001600160a01b03166110a6565b610432600480360360208110156106a457600080fd5b50356001600160a01b03166110c5565b610550600480360360208110156106ca57600080fd5b50356001600160a01b03166110e6565b61055060048036036101a08110156106f157600080fd5b60408051608081810183528435600290810b956020810135820b9594810135820b94606082013590920b936001600160a01b03848301351693928201926101208301919060a0840190600490839083908082843760009201919091525050604080516080818101909252929594938181019392509060049083908390808284376000920191909152509194506111689350505050565b6103fe61178d565b61032261179c565b6103fe6117ac565b61043260048036036101008110156107b657600080fd5b60408051608081810183528435946020810135946001600160a01b03948201358516946060830135169390820192610100830191908084019060049083908390808284376000920191909152509194506117c29350505050565b61087d600480360360a081101561082657600080fd5b6040805180820182528335600290810b946020810135820b946001600160801b0385830135169490820193919260a0840192916060850191908390839080828437600092019190915250919450611c009350505050565b6040805192835260208301919091528051918290030190f35b610341611c98565b6108a6611cf9565b604080516001600160801b039094168452602084019290925282820152519081900360600190f35b6103e2600480360360408110156108e457600080fd5b506001600160a01b038135169060200135611d7f565b61087d600480360360e081101561091057600080fd5b60408051608081810183528435946001600160a01b036020820135811695948201351693810192909160e08301919060608401906004908390839080828437600092019190915250919450611de79350505050565b6103e26004803603604081101561097b57600080fd5b506001600160a01b038135169060200135612189565b61043261219d565b6105506121b0565b61087d612224565b610550612334565b610550600480360360208110156109c757600080fd5b503560ff166123a6565b610322612455565b6103fe612465565b6108a6612474565b610550600480360360e08110156109ff57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060ff6080820135169060a08101359060c001356124d0565b61043260048036036040811015610a5057600080fd5b506001600160a01b0381358116916020013516612687565b61048a6126b2565b61055060048036036020811015610a8657600080fd5b50356001600160a01b03166126c2565b610322612769565b600854604080516339db007960e21b815290516000926001600160a01b03169163e76c01e49160048083019260e0929190829003018186803b158015610ae357600080fd5b505afa158015610af7573d6000803e3d6000fd5b505050506040513d60e0811015610b0d57600080fd5b5060200151919050565b60038054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ba35780601f10610b7857610100808354040283529160200191610ba3565b820191906000526020600020905b815481529060010190602001808311610b8657829003601f168201915b505050505090505b90565b6000610bc2610bbb612779565b848461277d565b5060015b92915050565b6009546001600160a01b031681565b600b546301000000900460020b81565b6008546001600160a01b031681565b60025490565b6000610c0d848484612869565b610c7d84610c19612779565b610c7885604051806060016040528060288152602001614633602891396001600160a01b038a16600090815260016020526040812090610c57612779565b6001600160a01b0316815260208101919091526040016000205491906129c4565b61277d565b5060015b9392505050565b600e5481565b60055460ff1690565b6000610ca1612a5b565b905090565b6000610bc2610cb3612779565b84610c788560016000610cc4612779565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490612b25565b6008546001600160a01b03163314610d0b57600080fd5b601054600160a81b900460ff161515600114610d2657600080fd5b601080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1690558315610d6b57600954610d6b906001600160a01b03163386612b7f565b8215610d8857600a54610d88906001600160a01b03163385612b7f565b50505050565b6010546001600160a01b031681565b600d5481565b600080600080600b60069054906101000a90046001600160a01b03166001600160a01b0316336001600160a01b031614610e11576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b610e19612beb565b5050600a54600954604080516370a0823160e01b81523060048201529051600093610f2f93600160c01b8204600290810b94600160d81b909304900b926001600160a01b03909116916370a08231916024808301926020929190829003018186803b158015610e8757600080fd5b505afa158015610e9b573d6000803e3d6000fd5b505050506040513d6020811015610eb157600080fd5b5051600a54604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b158015610efe57600080fd5b505afa158015610f12573d6000803e3d6000fd5b505050506040513d6020811015610f2857600080fd5b5051612c36565b600a548751919250610f6491600160c01b8204600290810b92600160d81b9004900b90849030908b60015b6020020151612cdc565b600b54600954604080516370a0823160e01b81523060048201529051610fc793600281810b946301000000909204900b926001600160a01b03909116916370a0823191602480820192602092909190829003018186803b158015610e8757600080fd5b600b546040880151919250610ff291600282810b9263010000009004900b90849030908b6003610f5a565b509193509193565b600b5460020b81565b600b54600160301b90046001600160a01b03163314611056576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b6110608585612ec0565b50600061106f86868686612c36565b9050611088868683308660006020020151876001610f5a565b505050505050565b600c5481565b601054600160a01b900460ff1681565b6001600160a01b0381166000908152602081905260409020545b919050565b6001600160a01b0381166000908152600660205260408120610bc690613237565b600b54600160301b90046001600160a01b03163314611139576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b600f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b600260075414156111c0576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600755600b54600160301b90046001600160a01b03163314611218576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b8560020b8760020b12801561124a5750600a54600160a81b9004600290810b810b9088900b8161124457fe5b0760020b155b80156112735750600a54600160a81b9004600290810b810b9087900b8161126d57fe5b0760020b155b61127c57600080fd5b8360020b8560020b1280156112ae5750600a54600160a81b9004600290810b810b9086900b816112a857fe5b0760020b155b80156112d75750600a54600160a81b9004600290810b810b9085900b816112d157fe5b0760020b155b6112e057600080fd5b8560020b8460020b1415806112fb57508660020b8560020b14155b61130457600080fd5b6001600160a01b03831661131757600080fd5b6010805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b038516179055611347612beb565b5050600a546000908190819061137290600160c01b8104600290810b91600160d81b9004900b61323b565b600b549295506001600160801b039182169450169150600090819081906113a790600281810b9163010000009004900b61323b565b600a549295506001600160801b0391821694501691506113f190600160c01b8104600290810b91600160d81b9004900b883060018c600060200201518d60015b60200201516132fd565b5050600b5461142190600281810b9163010000009004810b90869030906001908d905b60200201518d60036113e7565b50507fbc4c20ad04f161d631d9ce94d27659391196415aa3c42f6a71c62e905ece782d61144c610a9e565b600954604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561149757600080fd5b505afa1580156114ab573d6000803e3d6000fd5b505050506040513d60208110156114c157600080fd5b5051600a54604080516370a0823160e01b815230600482015290516001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561150e57600080fd5b505afa158015611522573d6000803e3d6000fd5b505050506040513d602081101561153857600080fd5b5051611544868a612b25565b61154e868a612b25565b611556610bfa565b6040805160029790970b87526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190a18c600a60186101000a81548162ffffff021916908360020b62ffffff1602179055508b600a601b6101000a81548162ffffff021916908360020b62ffffff160217905550611656600a60189054906101000a900460020b600a601b9054906101000a900460020b600960009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610e8757600080fd5b600a54895191975061168591600160c01b8204600290810b92600160d81b9004900b90899030908d6001610f5a565b8a600b60006101000a81548162ffffff021916908360020b62ffffff16021790555089600b60036101000a81548162ffffff021916908360020b62ffffff16021790555061174e600b60009054906101000a900460020b600b60039054906101000a900460020b600960009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610e8757600080fd5b600b5460408a015191945061177991600282810b9263010000009004900b90869030908d6003610f5a565b505060016007555050505050505050505050565b600f546001600160a01b031681565b600a54600160d81b900460020b81565b600b54600160301b90046001600160a01b031681565b60006002600754141561181c576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026007558515158061182f5750600085115b61183857600080fd5b600c54861115801561184c5750600d548511155b61185557600080fd5b6001600160a01b0384161580159061187657506001600160a01b0384163014155b6118ac576040805162461bcd60e51b8152602060048201526002602482015261746f60f01b604482015290519081900360640190fd5b600f546001600160a01b031633146118f1576040805162461bcd60e51b815260206004820152600360248201526257484560e81b604482015290519081900360640190fd5b6118f9612beb565b5050600061190d611908610a9e565b61354b565b905060006119416119276001600160a01b0384168061387d565b6ec097ce7bc90715b34b9f1000000000600160c01b6138d6565b905060008061194e612224565b90925090506119806119796ec097ce7bc90715b34b9f10000000006119738d8761387d565b90613985565b8a90612b25565b945089156119a0576009546119a0906001600160a01b031688308d6139ec565b88156119be57600a546119be906001600160a01b031688308c6139ec565b60006119c8610bfa565b90508015611b4a5760006119ef6ec097ce7bc90715b34b9f1000000000611973868861387d565b9050611a086119fe8285612b25565b611973898561387d565b601054909750600160a01b900460ff1615611b4857600a54600954604080516370a0823160e01b81523060048201529051600093611a8993600160c01b8204600290810b94600160d81b909304900b926001600160a01b03909116916370a08231916024808301926020929190829003018186803b158015610e8757600080fd5b600a548a51919250611ab891600160c01b8204600290810b92600160d81b9004900b90849030908e6001610f5a565b600b54600954604080516370a0823160e01b81523060048201529051611b1b93600281810b946301000000909204900b926001600160a01b03909116916370a0823191602480820192602092909190829003018186803b158015610e8757600080fd5b600b5460408b0151919250611b4691600282810b9263010000009004900b90849030908e6003610f5a565b505b505b611b548987613a5b565b60408051878152602081018d90528082018c905290516001600160a01b03808c1692908b16917f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f69181900360600190a3600e541580611bb55750600e548111155b611bec576040805162461bcd60e51b81526020600482015260036024820152620dac2f60eb1b604482015290519081900360640190fd5b505060016007555091979650505050505050565b600b546000908190600160301b90046001600160a01b03163314611c58576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b611c628686612ec0565b50611c8b8686611c7c8989896001600160801b0316613b4b565b865130906000908960016113e7565b9097909650945050505050565b60048054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610ba35780601f10610b7857610100808354040283529160200191610ba3565b600b5460009081908190819081908190611d2190600281810b9163010000009004900b61323b565b600b549295509093509150611d4590600281810b9163010000009004900b85613b8b565b9095509350611d5d856001600160801b038416612b25565b9450611d72846001600160801b038316612b25565b9350829550505050909192565b6000610bc2611d8c612779565b84610c78856040518060600160405280602581526020016146ef6025913960016000611db6612779565b6001600160a01b03908116825260208083019390935260409182016000908120918d168152925290205491906129c4565b60008060026007541415611e42576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260075585611e99576040805162461bcd60e51b815260206004820152600660248201527f7368617265730000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6001600160a01b038516611ed9576040805162461bcd60e51b8152602060048201526002602482015261746f60f01b604482015290519081900360640190fd5b611ee1612beb565b5050600a546000908190611f1f90600160c01b8104600290810b91600160d81b9004900b611f1082828d613b4b565b88518b906000908b60016113e7565b600b5491935091506000908190611f5590600281810b9163010000009004900b611f4a82828f613b4b565b8c60008c6002611414565b915091506000611ffe611f66610bfa565b6119738d600960009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fcc57600080fd5b505afa158015611fe0573d6000803e3d6000fd5b505050506040513d6020811015611ff657600080fd5b50519061387d565b9050600061207361200d610bfa565b6119738e600a60009054906101000a90046001600160a01b03166001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611fcc57600080fd5b9050811561209257600954612092906001600160a01b03168c84612b7f565b80156120af57600a546120af906001600160a01b03168c83612b7f565b6120c3826120bd8887612b25565b90612b25565b97506120d3816120bd8786612b25565b96506001600160a01b038a163314612118576040805162461bcd60e51b815260206004820152600360248201526237bbb760e91b604482015290519081900360640190fd5b6121228a8d613c35565b604080518d8152602081018a905280820189905290516001600160a01b03808e1692908d16917febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f9181900360600190a3505050505050600160078190555094509492505050565b6000610bc2612196612779565b8484612869565b6ec097ce7bc90715b34b9f100000000081565b600b54600160301b90046001600160a01b03163314612203576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b6010805460ff60a01b198116600160a01b9182900460ff1615909102179055565b600080600080612232612474565b9250925050600080612242611cf9565b600954604080516370a0823160e01b815230600482015290519396509194506122d0935085926120bd9289926001600160a01b0316916370a0823191602480820192602092909190829003018186803b15801561229e57600080fd5b505afa1580156122b2573d6000803e3d6000fd5b505050506040513d60208110156122c857600080fd5b505190612b25565b600a54604080516370a0823160e01b8152306004820152905192985061232a9284926120bd9288926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561229e57600080fd5b9450505050509091565b600b54600160301b90046001600160a01b03163314612387576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b600f805473ffffffffffffffffffffffffffffffffffffffff19169055565b600b54600160301b90046001600160a01b031633146123f9576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b600a805460ff808416600160a01b90810260ff60a01b199093169290921792839055604080519290930416815290517f91f2ade82ab0e77bb6823899e6daddc07e3da0e3ad998577e7c09c2f38943c439181900360200190a150565b600a54600160a81b900460020b81565b600a546001600160a01b031681565b6000806000806000806124a5600a60189054906101000a900460020b600a601b9054906101000a900460020b61323b565b600a549295509093509150611d4590600160c01b8104600290810b91600160d81b9004900b85613b8b565b83421115612525576040805162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015290519081900360640190fd5b6001600160a01b03871660009081526006602052604081207f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c99089908990899061256e90613237565b8960405160200180878152602001866001600160a01b03168152602001856001600160a01b03168152602001848152602001838152602001828152602001965050505050505060405160208183030381529060405280519060200120905060006125d782613d31565b905060006125e782878787613d7d565b9050896001600160a01b0316816001600160a01b03161461264f576040805162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e61747572650000604482015290519081900360640190fd5b6001600160a01b038a16600090815260066020526040902061267090613ef2565b61267b8a8a8a61277d565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600a54600160a01b900460ff1681565b600b54600160301b90046001600160a01b03163314612715576040805162461bcd60e51b815260206004820152600a60248201526937b7363c9037bbb732b960b11b604482015290519081900360640190fd5b6001600160a01b03811661272857600080fd5b600b80546001600160a01b03909216600160301b027fffffffffffff0000000000000000000000000000000000000000ffffffffffff909216919091179055565b600a54600160c01b900460020b81565b3390565b6001600160a01b0383166127c25760405162461bcd60e51b81526004018080602001828103825260248152602001806146a16024913960400191505060405180910390fd5b6001600160a01b0382166128075760405162461bcd60e51b81526004018080602001828103825260228152602001806145606022913960400191505060405180910390fd5b6001600160a01b03808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b0383166128ae5760405162461bcd60e51b815260040180806020018281038252602581526020018061467c6025913960400191505060405180910390fd5b6001600160a01b0382166128f35760405162461bcd60e51b815260040180806020018281038252602381526020018061451b6023913960400191505060405180910390fd5b6128fe838383612be6565b61293b81604051806060016040528060268152602001614582602691396001600160a01b03861660009081526020819052604090205491906129c4565b6001600160a01b03808516600090815260208190526040808220939093559084168152205461296a9082612b25565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115612a535760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612a18578181015183820152602001612a00565b50505050905090810190601f168015612a455780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60007f0000000000000000000000000000000000000000000000000000000000000089612a86613efb565b1415612ab357507f29f64510b611cff851a5db27e7995d26ac020411750e27e6fc448e8438872487610bab565b612b1e7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7fc0d183d2b6759ce4b3238d9d09d88b47cd87eb184ead0b4a71b0a36f43b82b5e7fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6613eff565b9050610bab565b600082820183811015610c81576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b179052612be6908490613f61565b505050565b600a546000908190612c1290600160c01b8104600290810b91600160d81b9004900b612ec0565b600b54909250612c3090600281810b9163010000009004900b612ec0565b90509091565b600080600860009054906101000a90046001600160a01b03166001600160a01b031663e76c01e46040518163ffffffff1660e01b815260040160e06040518083038186803b158015612c8757600080fd5b505afa158015612c9b573d6000803e3d6000fd5b505050506040513d60e0811015612cb157600080fd5b50519050612cd281612cc28861354b565b612ccb8861354b565b8787614012565b9695505050505050565b6001600160801b03841615611088576001601060156101000a81548160ff021916908315150217905550600080600860009054906101000a90046001600160a01b03166001600160a01b031663aafe29c030308b8b8b8b60405160200180826001600160a01b031681526020019150506040516020818303038152906040526040518763ffffffff1660e01b815260040180876001600160a01b03168152602001866001600160a01b031681526020018560020b81526020018460020b8152602001836001600160801b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612de6578181015183820152602001612dce565b50505050905090810190601f168015612e135780820380516001836020036101000a031916815260200191505b50975050505050505050606060405180830381600087803b158015612e3757600080fd5b505af1158015612e4b573d6000803e3d6000fd5b505050506040513d6060811015612e6157600080fd5b5080516020909101519092509050838210801590612e7f5750828110155b612eb6576040805162461bcd60e51b815260206004820152600360248201526250534360e81b604482015290519081900360640190fd5b5050505050505050565b6000612ecc838361323b565b50909150506001600160801b03811615610bc6576008546040805163a34123a760e01b8152600286810b600483015285900b602482015260006044820181905282516001600160a01b039094169363a34123a7936064808501949193918390030190829087803b158015612f3f57600080fd5b505af1158015612f53573d6000803e3d6000fd5b505050506040513d6040811015612f6957600080fd5b5050600854604080516309e3d67b60e31b8152306004820152600286810b602483015285900b60448201526001600160801b03606482018190526084820152815160009384936001600160a01b0390911692634f1eb3d89260a4808301939282900301818787803b158015612fdd57600080fd5b505af1158015612ff1573d6000803e3d6000fd5b505050506040513d604081101561300757600080fd5b508051602091820151600a546040805160ff600160a01b9093049290921682526001600160801b039384169482018590529290911681830181905291519294509092507f4606b8a47eb284e8e80929101ece6ab5fe8d4f8735acc56bd0c92ca872f2cfe7919081900360600190a1600a54600090613090908490600160a01b900460ff16613985565b1180156131115750600954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156130e357600080fd5b505afa1580156130f7573d6000803e3d6000fd5b505050506040513d602081101561310d57600080fd5b5051115b1561315257601054600a54613152916001600160a01b03169061313f908590600160a01b900460ff16613985565b6009546001600160a01b03169190612b7f565b600a5460009061316d908390600160a01b900460ff16613985565b1180156131ee5750600a54604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156131c057600080fd5b505afa1580156131d4573d6000803e3d6000fd5b505050506040513d60208110156131ea57600080fd5b5051115b1561322f57601054600a5461322f916001600160a01b03169061321c908490600160a01b900460ff16613985565b600a546001600160a01b03169190612b7f565b505092915050565b5490565b600080600080600030905062ffffff861662ffffff88168260181b1760181b179150600860009054906101000a90046001600160a01b03166001600160a01b031663514ea4bf836040518263ffffffff1660e01b81526004018082815260200191505060c06040518083038186803b1580156132b657600080fd5b505afa1580156132ca573d6000803e3d6000fd5b505050506040513d60c08110156132e057600080fd5b508051608082015160a09092015190999198509650945050505050565b6000806001600160801b0387161561353f576008546040805163a34123a760e01b815260028c810b60048301528b900b60248201526001600160801b038a166044820152815160009384936001600160a01b039091169263a34123a7926064808301939282900301818787803b15801561337657600080fd5b505af115801561338a573d6000803e3d6000fd5b505050506040513d60408110156133a057600080fd5b50805160209091015190925090508582108015906133be5750848110155b6133f5576040805162461bcd60e51b815260206004820152600360248201526250534360e81b604482015290519081900360640190fd5b60008761340a57613405836140ca565b613413565b6001600160801b035b905060008861342a57613425836140ca565b613433565b6001600160801b035b90506000826001600160801b0316118061345657506000816001600160801b0316115b1561353a57600860009054906101000a90046001600160a01b03166001600160a01b0316634f1eb3d88b8f8f86866040518663ffffffff1660e01b815260040180866001600160a01b031681526020018560020b81526020018460020b8152602001836001600160801b03168152602001826001600160801b03168152602001955050505050506040805180830381600087803b1580156134f657600080fd5b505af115801561350a573d6000803e3d6000fd5b505050506040513d604081101561352057600080fd5b5080516020909101516001600160801b0391821697501694505b505050505b97509795505050505050565b6000600282810b60171d90818418829003900b620d89e881111561359a576040805162461bcd60e51b81526020600482015260016024820152601560fa1b604482015290519081900360640190fd5b6000600182166135bb577001000000000000000000000000000000006135cd565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615613601576ffff97272373d413259a46990580e213a0260801c5b6004821615613620576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b600882161561363f576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b601082161561365e576fffcb9843d60f6159c9db58835c9266440260801c5b602082161561367d576fff973b41fa98c081472e6896dfb254c00260801c5b604082161561369c576fff2ea16466c96a3843ec78b326b528610260801c5b60808216156136bb576ffe5dee046a99a2a811c461f1969c30530260801c5b6101008216156136db576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b6102008216156136fb576ff987a7253ac413176f2b074cf7815e540260801c5b61040082161561371b576ff3392b0822b70005940c7a398e4b70f30260801c5b61080082161561373b576fe7159475a2c29b7443b29c7fa6e889d90260801c5b61100082161561375b576fd097f3bdfd2022b8845ad8f792aa58250260801c5b61200082161561377b576fa9f746462d870fdf8a65dc1f90e061e50260801c5b61400082161561379b576f70d869a156d2a1b890bb3df62baf32f70260801c5b6180008216156137bb576f31be135f97d08fd981231505542fcfa60260801c5b620100008216156137dc576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b620200008216156137fc576e5d6af8dedb81196699c329225ee6040260801c5b6204000082161561381b576d2216e584f5fa1ea926041bedfe980260801c5b62080000821615613838576b048a170391f7dc42444e8fa20260801c5b60008560020b131561385357806000198161384f57fe5b0490505b64010000000081061561386757600161386a565b60005b60ff16602082901c019350505050919050565b60008261388c57506000610bc6565b8282028284828161389957fe5b0414610c815760405162461bcd60e51b81526004018080602001828103825260218152602001806146126021913960400191505060405180910390fd5b600080806000198587098686029250828110908390030390508061390c576000841161390157600080fd5b508290049050610c81565b80841161391857600080fd5b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b60008082116139db576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b8183816139e457fe5b049392505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b179052610d88908590613f61565b6001600160a01b038216613ab6576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b613ac260008383612be6565b600254613acf9082612b25565b6002556001600160a01b038216600090815260208190526040902054613af59082612b25565b6001600160a01b0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600080613b58858561323b565b50509050613b82613b7d613b6a610bfa565b6119736001600160801b0385168761387d565b6140ca565b95945050505050565b6000806000600860009054906101000a90046001600160a01b03166001600160a01b031663e76c01e46040518163ffffffff1660e01b815260040160e06040518083038186803b158015613bde57600080fd5b505afa158015613bf2573d6000803e3d6000fd5b505050506040513d60e0811015613c0857600080fd5b50519050613c2881613c198861354b565b613c228861354b565b876140e1565b9250925050935093915050565b6001600160a01b038216613c7a5760405162461bcd60e51b815260040180806020018281038252602181526020018061465b6021913960400191505060405180910390fd5b613c8682600083612be6565b613cc38160405180606001604052806022815260200161453e602291396001600160a01b03851660009081526020819052604090205491906129c4565b6001600160a01b038316600090815260208190526040902055600254613ce9908261417d565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6000613d3b612a5b565b82604051602001808061190160f01b81525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050919050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115613dde5760405162461bcd60e51b81526004018080602001828103825260228152602001806145a86022913960400191505060405180910390fd5b8360ff16601b1480613df357508360ff16601c145b613e2e5760405162461bcd60e51b81526004018080602001828103825260228152602001806145f06022913960400191505060405180910390fd5b600060018686868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015613e8a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116613b82576040805162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b80546001019055565b4690565b6000838383613f0c613efb565b3060405160200180868152602001858152602001848152602001838152602001826001600160a01b03168152602001955050505050506040516020818303038152906040528051906020012090509392505050565b6000613fb6826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166141da9092919063ffffffff16565b805190915015612be657808060200190516020811015613fd557600080fd5b5051612be65760405162461bcd60e51b815260040180806020018281038252602a8152602001806146c5602a913960400191505060405180910390fd5b6000836001600160a01b0316856001600160a01b03161115614032579293925b846001600160a01b0316866001600160a01b03161161405d576140568585856141f1565b9050613b82565b836001600160a01b0316866001600160a01b031610156140bf5760006140848786866141f1565b90506000614093878986614254565b9050806001600160801b0316826001600160801b0316106140b457806140b6565b815b92505050613b82565b612cd2858584614254565b60006001600160801b038211156140dd57fe5b5090565b600080836001600160a01b0316856001600160a01b03161115614102579293925b846001600160a01b0316866001600160a01b03161161412d57614126858585614291565b9150614174565b836001600160a01b0316866001600160a01b0316101561416657614152868585614291565b915061415f8587856142fa565b9050614174565b6141718585856142fa565b90505b94509492505050565b6000828211156141d4576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60606141e9848460008561433d565b949350505050565b6000826001600160a01b0316846001600160a01b03161115614211579192915b6000614234856001600160a01b0316856001600160a01b0316600160601b6138d6565b9050613b8261424f84838888036001600160a01b03166138d6565b614498565b6000826001600160a01b0316846001600160a01b03161115614274579192915b6141e961424f83600160601b8787036001600160a01b03166138d6565b6000826001600160a01b0316846001600160a01b031611156142b1579192915b836001600160a01b03166142ea606060ff16846001600160801b0316901b8686036001600160a01b0316866001600160a01b03166138d6565b816142f157fe5b04949350505050565b6000826001600160a01b0316846001600160a01b0316111561431a579192915b6141e9826001600160801b03168585036001600160a01b0316600160601b6138d6565b60608247101561437e5760405162461bcd60e51b81526004018080602001828103825260268152602001806145ca6026913960400191505060405180910390fd5b614387856144ae565b6143d8576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b602083106144165780518252601f1990920191602091820191016143f7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614478576040519150601f19603f3d011682016040523d82523d6000602084013e61447d565b606091505b509150915061448d8282866144b4565b979650505050505050565b806001600160801b03811681146110c057600080fd5b3b151590565b606083156144c3575081610c81565b8251156144d35782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315612a18578181015183820152602001612a0056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636545434453413a20696e76616c6964207369676e6174757265202773272076616c7565416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c45434453413a20696e76616c6964207369676e6174757265202776272076616c7565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa164736f6c6343000706000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e7e0eb9f6bcccfe847fdf62a3628319a092f11a2000000000000000000000000ade38bd2e8d5a52e60047affe6e595bb5e61923a000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000961555344432d4441490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000961555344432d4441490000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _pool (address): 0xe7E0eB9F6bCcCfe847fDf62a3628319a092F11a2
Arg [1] : _owner (address): 0xADE38bd2E8D5A52E60047AfFe6E595bB5E61923A
Arg [2] : name (string): aUSDC-DAI
Arg [3] : symbol (string): aUSDC-DAI
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000e7e0eb9f6bcccfe847fdf62a3628319a092f11a2
Arg [1] : 000000000000000000000000ade38bd2e8d5a52e60047affe6e595bb5e61923a
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [5] : 61555344432d4441490000000000000000000000000000000000000000000000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [7] : 61555344432d4441490000000000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
[ 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.