Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 9 from a total of 9 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Refund Native To... | 17125123 | 646 days ago | IN | 0 ETH | 0.00310365 | ||||
Place Relative O... | 16972356 | 667 days ago | IN | 0.5 ETH | 0.000577 | ||||
Place Relative O... | 16940280 | 672 days ago | IN | 0.1 ETH | 0.00068519 | ||||
Place Maker Orde... | 16905166 | 677 days ago | IN | 0 ETH | 0.00046125 | ||||
Place Maker Orde... | 16904481 | 677 days ago | IN | 0.01079591 ETH | 0.00053446 | ||||
Place Maker Orde... | 16893927 | 678 days ago | IN | 0 ETH | 0.00052077 | ||||
Place Maker Orde... | 16893674 | 678 days ago | IN | 0 ETH | 0.00051414 | ||||
Place Relative O... | 16883232 | 680 days ago | IN | 0.45 ETH | 0.00035752 | ||||
Place Relative O... | 16883224 | 680 days ago | IN | 0 ETH | 0.00037349 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
17125123 | 646 days ago | 1.06079591 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
MakerOrderManager
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 100000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity =0.8.9; pragma abicoder v2; import "@openzeppelin/contracts/utils/math/Math.sol"; import "@gridexprotocol/core/contracts/interfaces/IGrid.sol"; import "@gridexprotocol/core/contracts/interfaces/IGridParameters.sol"; import "@gridexprotocol/core/contracts/interfaces/IGridFactory.sol"; import "@gridexprotocol/core/contracts/libraries/GridAddress.sol"; import "@gridexprotocol/core/contracts/libraries/CallbackValidator.sol"; import "@gridexprotocol/core/contracts/libraries/BoundaryMath.sol"; import "./interfaces/IMakerOrderManager.sol"; import "./interfaces/IRelativeOrderManager.sol"; import "./Multicall.sol"; import "./AbstractPayments.sol"; import "./AbstractSelfPermit2612.sol"; /// @title The implementation for the maker order manager contract MakerOrderManager is IMakerOrderManager, IRelativeOrderManager, AbstractPayments, AbstractSelfPermit2612, Multicall { constructor(address _gridFactory, address _weth9) AbstractPayments(_gridFactory, _weth9) {} struct PlaceMakerOrderCalldata { GridAddress.GridKey gridKey; address payer; } /// @inheritdoc IGridPlaceMakerOrderCallback function gridexPlaceMakerOrderCallback(uint256 amount0, uint256 amount1, bytes calldata data) external override { PlaceMakerOrderCalldata memory decodeData = abi.decode(data, (PlaceMakerOrderCalldata)); CallbackValidator.validate(gridFactory, decodeData.gridKey); if (amount0 > 0) pay(decodeData.gridKey.token0, decodeData.payer, _msgSender(), amount0); if (amount1 > 0) pay(decodeData.gridKey.token1, decodeData.payer, _msgSender(), amount1); } /// @inheritdoc IMakerOrderManager function initialize(InitializeParameters calldata parameters) external payable { GridAddress.GridKey memory gridKey = GridAddress.gridKey( parameters.tokenA, parameters.tokenB, parameters.resolution ); address grid = GridAddress.computeAddress(gridFactory, gridKey); address recipient = parameters.recipient == address(0) ? _msgSender() : parameters.recipient; IGrid(grid).initialize( IGridParameters.InitializeParameters({ priceX96: parameters.priceX96, recipient: recipient, orders0: parameters.orders0, orders1: parameters.orders1 }), abi.encode(PlaceMakerOrderCalldata({gridKey: gridKey, payer: _msgSender()})) ); } /// @inheritdoc IMakerOrderManager function createGridAndInitialize(InitializeParameters calldata parameters) external payable { address grid = IGridFactory(gridFactory).createGrid( parameters.tokenA, parameters.tokenB, parameters.resolution ); address recipient = parameters.recipient == address(0) ? _msgSender() : parameters.recipient; IGrid(grid).initialize( IGridParameters.InitializeParameters({ priceX96: parameters.priceX96, recipient: recipient, orders0: parameters.orders0, orders1: parameters.orders1 }), abi.encode( PlaceMakerOrderCalldata({ gridKey: GridAddress.gridKey(parameters.tokenA, parameters.tokenB, parameters.resolution), payer: _msgSender() }) ) ); } /// @inheritdoc IMakerOrderManager function placeMakerOrder( PlaceOrderParameters calldata parameters ) external payable checkDeadline(parameters.deadline) returns (uint256 orderId) { GridAddress.GridKey memory gridKey = GridAddress.gridKey( parameters.tokenA, parameters.tokenB, parameters.resolution ); address grid = GridAddress.computeAddress(gridFactory, gridKey); address recipient = parameters.recipient == address(0) ? _msgSender() : parameters.recipient; orderId = _placeMakerOrder( grid, gridKey, recipient, parameters.zero, parameters.boundaryLower, parameters.amount ); } function _placeMakerOrder( address grid, GridAddress.GridKey memory gridKey, address recipient, bool zero, int24 boundaryLower, uint128 amount ) private returns (uint256 orderId) { orderId = IGrid(grid).placeMakerOrder( IGridParameters.PlaceOrderParameters({ recipient: recipient, zero: zero, boundaryLower: boundaryLower, amount: amount }), abi.encode(PlaceMakerOrderCalldata({gridKey: gridKey, payer: _msgSender()})) ); } /// @inheritdoc IMakerOrderManager function placeMakerOrderInBatch( PlaceOrderInBatchParameters calldata parameters ) external payable checkDeadline(parameters.deadline) returns (uint256[] memory orderIds) { GridAddress.GridKey memory gridKey = GridAddress.gridKey( parameters.tokenA, parameters.tokenB, parameters.resolution ); address grid = GridAddress.computeAddress(gridFactory, gridKey); address recipient = parameters.recipient == address(0) ? _msgSender() : parameters.recipient; orderIds = IGrid(grid).placeMakerOrderInBatch( IGridParameters.PlaceOrderInBatchParameters({ recipient: recipient, zero: parameters.zero, orders: parameters.orders }), abi.encode(PlaceMakerOrderCalldata({gridKey: gridKey, payer: _msgSender()})) ); } /// @inheritdoc IRelativeOrderManager function placeRelativeOrder( RelativeOrderParameters calldata parameters ) external payable checkDeadline(parameters.deadline) returns (uint256 orderId) { // MOM_AIZ: amount is zero require(parameters.amount > 0, "MOM_AIZ"); GridAddress.GridKey memory gridKey = GridAddress.gridKey( parameters.tokenA, parameters.tokenB, parameters.resolution ); address grid = GridAddress.computeAddress(gridFactory, gridKey); (uint160 priceX96, , , ) = IGrid(grid).slot0(); uint160 targetPriceX96 = parameters.priceDeltaX96 > 0 ? priceX96 + uint160(parameters.priceDeltaX96) : priceX96 - uint160(-parameters.priceDeltaX96); // MOM_POR: price out of range require(BoundaryMath.isPriceX96InRange(targetPriceX96), "MOM_POR"); require( targetPriceX96 >= parameters.priceMinimumX96 && targetPriceX96 <= parameters.priceMaximumX96, "MOM_POR" ); int24 boundaryLower = BoundaryMath.rewriteToValidBoundaryLower( BoundaryMath.getBoundaryLowerAtBoundary( BoundaryMath.getBoundaryAtPriceX96(targetPriceX96), parameters.resolution ), parameters.resolution ); // when the input is token1 and the price has reached the right boundary price, // we need to subtract a resolution from boundary lower if (!parameters.zero) { uint160 priceMaxX96 = BoundaryMath.getPriceX96AtBoundary(boundaryLower); boundaryLower = priceMaxX96 == targetPriceX96 ? BoundaryMath.rewriteToValidBoundaryLower( boundaryLower -= parameters.resolution, parameters.resolution ) // avoid underflow : boundaryLower; } address recipient = parameters.recipient == address(0) ? _msgSender() : parameters.recipient; orderId = _placeMakerOrder(grid, gridKey, recipient, parameters.zero, boundaryLower, parameters.amount); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; /// @title Callback for IGrid#placeMakerOrder /// @notice Any contract that calls IGrid#placeMakerOrder must implement this interface interface IGridPlaceMakerOrderCallback { /// @notice Called to `msg.sender` after executing a place maker order via IGrid#placeMakerOrder /// @dev In this implementation, you are required to pay the grid tokens owed for the maker order. /// The caller of the method must be a grid deployed by the canonical GridFactory. /// At most one of amount0 and amount1 is a positive number /// @param amount0 The grid will receive the amount of token0 upon placement of the maker order. /// In the receiving case, the callback must send this amount of token0 to the grid /// @param amount1 The grid will receive the amount of token1 upon placement of the maker order. /// In the receiving case, the callback must send this amount of token1 to the grid /// @param data Any data passed through by the caller via the IGrid#placeMakerOrder call function gridexPlaceMakerOrderCallback(uint256 amount0, uint256 amount1, bytes calldata data) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import "./IGridStructs.sol"; import "./IGridParameters.sol"; /// @title The interface for Gridex grid interface IGrid { ///==================================== Grid States ==================================== /// @notice The first token in the grid, after sorting by address function token0() external view returns (address); /// @notice The second token in the grid, after sorting by address function token1() external view returns (address); /// @notice The step size in initialized boundaries for a grid created with a given fee function resolution() external view returns (int24); /// @notice The fee paid to the grid denominated in hundredths of a bip, i.e. 1e-6 function takerFee() external view returns (int24); /// @notice The 0th slot of the grid holds a lot of values that can be gas-efficiently accessed /// externally as a single method /// @return priceX96 The current price of the grid, as a Q64.96 /// @return boundary The current boundary of the grid /// @return blockTimestamp The time the oracle was last updated /// @return unlocked Whether the grid is unlocked or not function slot0() external view returns (uint160 priceX96, int24 boundary, uint32 blockTimestamp, bool unlocked); /// @notice Returns the boundary information of token0 /// @param boundary The boundary of the grid /// @return bundle0Id The unique identifier of bundle0 /// @return bundle1Id The unique identifier of bundle1 /// @return makerAmountRemaining The remaining amount of token0 that can be swapped out, /// which is the sum of bundle0 and bundle1 function boundaries0( int24 boundary ) external view returns (uint64 bundle0Id, uint64 bundle1Id, uint128 makerAmountRemaining); /// @notice Returns the boundary information of token1 /// @param boundary The boundary of the grid /// @return bundle0Id The unique identifier of bundle0 /// @return bundle1Id The unique identifier of bundle1 /// @return makerAmountRemaining The remaining amount of token1 that can be swapped out, /// which is the sum of bundle0 and bundle1 function boundaries1( int24 boundary ) external view returns (uint64 bundle0Id, uint64 bundle1Id, uint128 makerAmountRemaining); /// @notice Returns 256 packed boundary initialized boolean values for token0 function boundaryBitmaps0(int16 wordPos) external view returns (uint256 word); /// @notice Returns 256 packed boundary initialized boolean values for token1 function boundaryBitmaps1(int16 wordPos) external view returns (uint256 word); /// @notice Returns the amount owed for token0 and token1 /// @param owner The address of owner /// @return token0 The amount of token0 owed /// @return token1 The amount of token1 owed function tokensOweds(address owner) external view returns (uint128 token0, uint128 token1); /// @notice Returns the information of a given bundle /// @param bundleId The unique identifier of the bundle /// @return boundaryLower The lower boundary of the bundle /// @return zero When zero is true, it represents token0, otherwise it represents token1 /// @return makerAmountTotal The total amount of token0 or token1 that the maker added /// @return makerAmountRemaining The remaining amount of token0 or token1 that can be swapped out from the makers /// @return takerAmountRemaining The remaining amount of token0 or token1 that have been swapped in from the takers /// @return takerFeeAmountRemaining The remaining amount of fees that takers have paid in function bundles( uint64 bundleId ) external view returns ( int24 boundaryLower, bool zero, uint128 makerAmountTotal, uint128 makerAmountRemaining, uint128 takerAmountRemaining, uint128 takerFeeAmountRemaining ); /// @notice Returns the information of a given order /// @param orderId The unique identifier of the order /// @return bundleId The unique identifier of the bundle -- represents which bundle this order belongs to /// @return owner The address of the owner of the order /// @return amount The amount of token0 or token1 to add function orders(uint256 orderId) external view returns (uint64 bundleId, address owner, uint128 amount); ///==================================== Grid Actions ==================================== /// @notice Initializes the grid with the given parameters /// @dev The caller of this method receives a callback in the form of /// IGridPlaceMakerOrderCallback#gridexPlaceMakerOrderCallback. /// When initializing the grid, token0 and token1's liquidity must be added simultaneously. /// @param parameters The parameters used to initialize the grid /// @param data Any data to be passed through to the callback /// @return orderIds0 The unique identifiers of the orders for token0 /// @return orderIds1 The unique identifiers of the orders for token1 function initialize( IGridParameters.InitializeParameters memory parameters, bytes calldata data ) external returns (uint256[] memory orderIds0, uint256[] memory orderIds1); /// @notice Swaps token0 for token1, or vice versa /// @dev The caller of this method receives a callback in the form of IGridSwapCallback#gridexSwapCallback /// @param recipient The address to receive the output of the swap /// @param zeroForOne The swap direction, true for token0 to token1 and false otherwise /// @param amountSpecified The amount of the swap, configured as an exactInput (positive) /// or an exactOutput (negative) /// @param priceLimitX96 Swap price limit: if zeroForOne, the price will not be less than this value after swap, /// if oneForZero, it will not be greater than this value after swap, as a Q64.96 /// @param data Any data to be passed through to the callback /// @return amount0 The balance change of the grid's token0. When negative, it will reduce the balance /// by the exact amount. When positive, it will increase by at least this amount /// @return amount1 The balance change of the grid's token1. When negative, it will reduce the balance /// by the exact amount. When positive, it will increase by at least this amount. function swap( address recipient, bool zeroForOne, int256 amountSpecified, uint160 priceLimitX96, bytes calldata data ) external returns (int256 amount0, int256 amount1); /// @notice Places a maker order on the grid /// @dev The caller of this method receives a callback in the form of /// IGridPlaceMakerOrderCallback#gridexPlaceMakerOrderCallback /// @param parameters The parameters used to place the maker order /// @param data Any data to be passed through to the callback /// @return orderId The unique identifier of the order function placeMakerOrder( IGridParameters.PlaceOrderParameters memory parameters, bytes calldata data ) external returns (uint256 orderId); /// @notice Places maker orders on the grid /// @dev The caller of this method receives a callback in the form of /// IGridPlaceMakerOrderCallback#gridexPlaceMakerOrderCallback /// @param parameters The parameters used to place the maker orders /// @param data Any data to be passed through to the callback /// @return orderIds The unique identifiers of the orders function placeMakerOrderInBatch( IGridParameters.PlaceOrderInBatchParameters memory parameters, bytes calldata data ) external returns (uint256[] memory orderIds); /// @notice Settles a maker order /// @param orderId The unique identifier of the order /// @return amount0 The amount of token0 that the maker received /// @return amount1 The amount of token1 that the maker received function settleMakerOrder(uint256 orderId) external returns (uint128 amount0, uint128 amount1); /// @notice Settle maker order and collect /// @param recipient The address to receive the output of the settlement /// @param orderId The unique identifier of the order /// @param unwrapWETH9 Whether to unwrap WETH9 to ETH /// @return amount0 The amount of token0 that the maker received /// @return amount1 The amount of token1 that the maker received function settleMakerOrderAndCollect( address recipient, uint256 orderId, bool unwrapWETH9 ) external returns (uint128 amount0, uint128 amount1); /// @notice Settles maker orders and collects in a batch /// @param recipient The address to receive the output of the settlement /// @param orderIds The unique identifiers of the orders /// @param unwrapWETH9 Whether to unwrap WETH9 to ETH /// @return amount0Total The total amount of token0 that the maker received /// @return amount1Total The total amount of token1 that the maker received function settleMakerOrderAndCollectInBatch( address recipient, uint256[] memory orderIds, bool unwrapWETH9 ) external returns (uint128 amount0Total, uint128 amount1Total); /// @notice For flash swaps. The caller borrows assets and returns them in the callback of the function, /// in addition to a fee /// @dev The caller of this function receives a callback in the form of IGridFlashCallback#gridexFlashCallback /// @param recipient The address which will receive the token0 and token1 /// @param amount0 The amount of token0 to receive /// @param amount1 The amount of token1 to receive /// @param data Any data to be passed through to the callback function flash(address recipient, uint256 amount0, uint256 amount1, bytes calldata data) external; /// @notice Collects tokens owed /// @param recipient The address to receive the collected fees /// @param amount0Requested The maximum amount of token0 to send. /// Set to 0 if fees should only be collected in token1. /// @param amount1Requested The maximum amount of token1 to send. /// Set to 0 if fees should only be collected in token0. /// @return amount0 The amount of fees collected in token0 /// @return amount1 The amount of fees collected in token1 function collect( address recipient, uint128 amount0Requested, uint128 amount1Requested ) external returns (uint128 amount0, uint128 amount1); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; /// @title The interface for Gridex grid factory interface IGridFactory { /// @notice Emitted when a new resolution is enabled for grid creation via the grid factory /// @param resolution The step size in initialized boundaries for a grid created with a given fee /// @param takerFee The taker fee, denominated in hundredths of a bip (i.e. 1e-6) event ResolutionEnabled(int24 indexed resolution, int24 indexed takerFee); /// @notice Emitted upon grid creation /// @param token0 The first token in the grid, after sorting by address /// @param token1 The first token in the grid, after sorting by address /// @param resolution The step size in initialized boundaries for a grid created with a given fee /// @param grid The address of the deployed grid event GridCreated(address indexed token0, address indexed token1, int24 indexed resolution, address grid); /// @notice Returns the taker fee for the given resolution if enabled. Else, returns 0. /// @dev A resolution can never be removed, so this value should be hard coded or cached in the calling context /// @param resolution The enabled resolution /// @return takerFee The taker fee, denominated in hundredths of a bip (i.e. 1e-6) function resolutions(int24 resolution) external view returns (int24 takerFee); /// @notice The implementation address of the price oracle function priceOracle() external view returns (address); /// @notice Returns the grid address for a given token pair and a resolution. Returns 0 if the pair does not exist. /// @dev tokenA and tokenB may be passed in, in the order of either token0/token1 or token1/token0 /// @param tokenA The contract address of either token0 or token1 /// @param tokenB The contract address of the other token /// @param resolution The step size in initialized boundaries for a grid created with a given fee /// @return grid The grid address function grids(address tokenA, address tokenB, int24 resolution) external view returns (address grid); /// @notice Concat grid creation code bytes /// @dev Split the creationCode of the Grid contract into two parts, so that the Gas Limit of particular networks can be met when deploying. /// @param gridSuffixCreationCode This parameter is the second half of the creationCode of the Grid contract. function concatGridSuffixCreationCode(bytes memory gridSuffixCreationCode) external; /// @notice Creates a grid for a given pair of tokens and resolution /// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. /// @param tokenA One token of the grid token pair /// @param tokenB The other token of the grid token pair /// @param resolution The step size in initialized boundaries for a grid created with a given fee /// @return grid The address of the deployed grid function createGrid(address tokenA, address tokenB, int24 resolution) external returns (address grid); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; interface IGridParameters { /// @dev Parameters for initializing the grid struct InitializeParameters { /// @dev The initial price of the grid, as a Q64.96. /// Price is represented as an amountToken1/amountToken0 Q64.96 value. uint160 priceX96; /// @dev The address to receive orders address recipient; /// @dev Represents the order parameters for token0 BoundaryLowerWithAmountParameters[] orders0; /// @dev Represents the order parameters for token1 BoundaryLowerWithAmountParameters[] orders1; } /// @dev Parameters for placing an order struct PlaceOrderParameters { /// @dev The address to receive the order address recipient; /// @dev When zero is true, it represents token0, otherwise it represents token1 bool zero; /// @dev The lower boundary of the order int24 boundaryLower; /// @dev The amount of token0 or token1 to add uint128 amount; } struct PlaceOrderInBatchParameters { /// @dev The address to receive the order address recipient; /// @dev When zero is true, it represents token0, otherwise it represents token1 bool zero; BoundaryLowerWithAmountParameters[] orders; } struct BoundaryLowerWithAmountParameters { /// @dev The lower boundary of the order int24 boundaryLower; /// @dev The amount of token0 or token1 to add uint128 amount; } /// @dev Status during swap struct SwapState { /// @dev When true, token0 is swapped for token1, otherwise token1 is swapped for token0 bool zeroForOne; /// @dev The remaining amount of the swap, which implicitly configures /// the swap as exact input (positive), or exact output (negative) int256 amountSpecifiedRemaining; /// @dev The calculated amount to be inputted uint256 amountInputCalculated; /// @dev The calculated amount of fee to be inputted uint256 feeAmountInputCalculated; /// @dev The calculated amount to be outputted uint256 amountOutputCalculated; /// @dev The price of the grid, as a Q64.96 uint160 priceX96; uint160 priceLimitX96; /// @dev The boundary of the grid int24 boundary; /// @dev The lower boundary of the grid int24 boundaryLower; uint160 initializedBoundaryLowerPriceX96; uint160 initializedBoundaryUpperPriceX96; /// @dev Whether the swap has been completed bool stopSwap; } struct SwapForBoundaryState { /// @dev The price indicated by the lower boundary, as a Q64.96 uint160 boundaryLowerPriceX96; /// @dev The price indicated by the upper boundary, as a Q64.96 uint160 boundaryUpperPriceX96; /// @dev The price indicated by the lower or upper boundary, as a Q64.96. /// When using token0 to exchange token1, it is equal to boundaryLowerPriceX96, /// otherwise it is equal to boundaryUpperPriceX96 uint160 boundaryPriceX96; /// @dev The price of the grid, as a Q64.96 uint160 priceX96; } struct UpdateBundleForTakerParameters { /// @dev The amount to be swapped in to bundle0 uint256 amountInUsed; /// @dev The remaining amount to be swapped in to bundle1 uint256 amountInRemaining; /// @dev The amount to be swapped out to bundle0 uint128 amountOutUsed; /// @dev The remaining amount to be swapped out to bundle1 uint128 amountOutRemaining; /// @dev The amount to be paid to bundle0 uint128 takerFeeForMakerAmountUsed; /// @dev The amount to be paid to bundle1 uint128 takerFeeForMakerAmountRemaining; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; interface IGridStructs { struct Bundle { int24 boundaryLower; bool zero; uint128 makerAmountTotal; uint128 makerAmountRemaining; uint128 takerAmountRemaining; uint128 takerFeeAmountRemaining; } struct Boundary { uint64 bundle0Id; uint64 bundle1Id; uint128 makerAmountRemaining; } struct Order { uint64 bundleId; address owner; uint128 amount; } struct TokensOwed { uint128 token0; uint128 token1; } struct Slot0 { uint160 priceX96; int24 boundary; uint32 blockTimestamp; bool unlocked; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; interface IWETHMinimum { function deposit() external payable; function transfer(address dst, uint256 wad) external returns (bool); function withdraw(uint256) external; function approve(address guy, uint256 wad) external returns (bool); function balanceOf(address dst) external view returns (uint256); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; library BoundaryMath { int24 public constant MIN_BOUNDARY = -527400; int24 public constant MAX_BOUNDARY = 443635; /// @dev The minimum value that can be returned from #getPriceX96AtBoundary. Equivalent to getPriceX96AtBoundary(MIN_BOUNDARY) uint160 internal constant MIN_RATIO = 989314; /// @dev The maximum value that can be returned from #getPriceX96AtBoundary. Equivalent to getPriceX96AtBoundary(MAX_BOUNDARY) uint160 internal constant MAX_RATIO = 1461300573427867316570072651998408279850435624081; /// @dev Checks if a boundary is divisible by a resolution /// @param boundary The boundary to check /// @param resolution The step size in initialized boundaries for a grid created with a given fee /// @return isValid Whether or not the boundary is valid function isValidBoundary(int24 boundary, int24 resolution) internal pure returns (bool isValid) { return boundary % resolution == 0; } /// @dev Checks if a boundary is within the valid range /// @param boundary The boundary to check /// @return inRange Whether or not the boundary is in range function isInRange(int24 boundary) internal pure returns (bool inRange) { return boundary >= MIN_BOUNDARY && boundary <= MAX_BOUNDARY; } /// @dev Checks if a price is within the valid range /// @param priceX96 The price to check, as a Q64.96 /// @return inRange Whether or not the price is in range function isPriceX96InRange(uint160 priceX96) internal pure returns (bool inRange) { return priceX96 >= MIN_RATIO && priceX96 <= MAX_RATIO; } /// @notice Calculates the price at a given boundary /// @dev priceX96 = pow(1.0001, boundary) * 2**96 /// @param boundary The boundary to calculate the price at /// @return priceX96 The price at the boundary, as a Q64.96 function getPriceX96AtBoundary(int24 boundary) internal pure returns (uint160 priceX96) { unchecked { uint256 absBoundary = boundary < 0 ? uint256(-int256(boundary)) : uint24(boundary); uint256 ratio = absBoundary & 0x1 != 0 ? 0xfff97272373d413259a46990580e213a : 0x100000000000000000000000000000000; if (absBoundary & 0x2 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128; if (absBoundary & 0x4 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128; if (absBoundary & 0x8 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128; if (absBoundary & 0x10 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128; if (absBoundary & 0x20 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128; if (absBoundary & 0x40 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128; if (absBoundary & 0x80 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128; if (absBoundary & 0x100 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128; if (absBoundary & 0x200 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128; if (absBoundary & 0x400 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; if (absBoundary & 0x800 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; if (absBoundary & 0x1000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; if (absBoundary & 0x2000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; if (absBoundary & 0x4000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; if (absBoundary & 0x8000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; if (absBoundary & 0x10000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; if (absBoundary & 0x20000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; if (absBoundary & 0x40000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; if (absBoundary & 0x80000 != 0) ratio = (ratio * 0x149b34ee7ac263) >> 128; if (boundary > 0) ratio = type(uint256).max / ratio; // this divides by 1<<32 and rounds up to go from a Q128.128 to a Q128.96. // due to out boundary input limitations, we then proceed to downcast as the // result will always fit within 160 bits. // we round up in the division so that getBoundaryAtPriceX96 of the output price is always consistent priceX96 = uint160((ratio + 0xffffffff) >> 32); } } /// @notice Calculates the boundary at a given price /// @param priceX96 The price to calculate the boundary at, as a Q64.96 /// @return boundary The boundary at the price function getBoundaryAtPriceX96(uint160 priceX96) internal pure returns (int24 boundary) { unchecked { uint256 ratio = uint256(priceX96) << 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 log10001 = log_2 * 127869479499801913173570; // 128.128 number int24 boundaryLow = int24((log10001 - 1701496478404566090792001455681771637) >> 128); int24 boundaryHi = int24((log10001 + 289637967442836604689790891002483458648) >> 128); boundary = boundaryLow == boundaryHi ? boundaryLow : getPriceX96AtBoundary(boundaryHi) <= priceX96 ? boundaryHi : boundaryLow; } } /// @dev Returns the lower boundary for the given boundary and resolution. /// The lower boundary may not be valid (if out of the boundary range) /// @param boundary The boundary to get the lower boundary for /// @param resolution The step size in initialized boundaries for a grid created with a given fee /// @return boundaryLower The lower boundary for the given boundary and resolution function getBoundaryLowerAtBoundary(int24 boundary, int24 resolution) internal pure returns (int24 boundaryLower) { unchecked { return boundary - (((boundary % resolution) + resolution) % resolution); } } /// @dev Rewrite the lower boundary that is not in the range to a valid value /// @param boundaryLower The lower boundary to rewrite /// @param resolution The step size in initialized boundaries for a grid created with a given fee /// @return validBoundaryLower The valid lower boundary function rewriteToValidBoundaryLower( int24 boundaryLower, int24 resolution ) internal pure returns (int24 validBoundaryLower) { unchecked { if (boundaryLower < MIN_BOUNDARY) return boundaryLower + resolution; else if (boundaryLower + resolution > MAX_BOUNDARY) return boundaryLower - resolution; else return boundaryLower; } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import "./GridAddress.sol"; library CallbackValidator { /// @dev Validates the `msg.sender` is the canonical grid address for the given parameters /// @param gridFactory The address of the grid factory /// @param gridKey The grid key to compute the canonical address for the grid function validate(address gridFactory, GridAddress.GridKey memory gridKey) internal view { // CV_IC: invalid caller require(GridAddress.computeAddress(gridFactory, gridKey) == msg.sender, "CV_IC"); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/Create2.sol"; library GridAddress { bytes32 internal constant GRID_BYTES_CODE_HASH = 0x884a6891a166f885bf6f0a3b330a25e41d1761a5aa091110a229d9a0e34b2c36; struct GridKey { address token0; address token1; int24 resolution; } /// @notice Constructs the grid key for the given parameters /// @dev tokenA and tokenB may be passed in, in the order of either token0/token1 or token1/token0 /// @param tokenA The contract address of either token0 or token1 /// @param tokenB The contract address of the other token /// @param resolution The step size in initialized boundaries for a grid created with a given fee /// @return key The grid key to compute the canonical address for the grid function gridKey(address tokenA, address tokenB, int24 resolution) internal pure returns (GridKey memory key) { if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); return GridKey(tokenA, tokenB, resolution); } /// @dev Computes the CREATE2 address for a grid with the given parameters /// @param gridFactory The address of the grid factory /// @param key The grid key to compute the canonical address for the grid /// @return grid The computed address function computeAddress(address gridFactory, GridKey memory key) internal pure returns (address grid) { require(key.token0 < key.token1); return Create2.computeAddress( keccak256(abi.encode(key.token0, key.token1, key.resolution)), GRID_BYTES_CODE_HASH, gridFactory ); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^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 // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev 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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.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 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' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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 require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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"); (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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Create2.sol) pragma solidity ^0.8.0; /** * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer. * `CREATE2` can be used to compute in advance the address where a smart * contract will be deployed, which allows for interesting new mechanisms known * as 'counterfactual interactions'. * * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more * information. */ library Create2 { /** * @dev Deploys a contract using `CREATE2`. The address where the contract * will be deployed can be known in advance via {computeAddress}. * * The bytecode for a contract can be obtained from Solidity with * `type(contractName).creationCode`. * * Requirements: * * - `bytecode` must not be empty. * - `salt` must have not been used for `bytecode` already. * - the factory must have a balance of at least `amount`. * - if `amount` is non-zero, `bytecode` must have a `payable` constructor. */ function deploy( uint256 amount, bytes32 salt, bytes memory bytecode ) internal returns (address addr) { require(address(this).balance >= amount, "Create2: insufficient balance"); require(bytecode.length != 0, "Create2: bytecode length is zero"); /// @solidity memory-safe-assembly assembly { addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt) } require(addr != address(0), "Create2: Failed on deploy"); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the * `bytecodeHash` or `salt` will result in a new destination address. */ function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) { return computeAddress(salt, bytecodeHash, address(this)); } /** * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}. */ function computeAddress( bytes32 salt, bytes32 bytecodeHash, address deployer ) internal pure returns (address addr) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) // Get free memory pointer // | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... | // |-------------------|---------------------------------------------------------------------------| // | bytecodeHash | CCCCCCCCCCCCC...CC | // | salt | BBBBBBBBBBBBB...BB | // | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA | // | 0xFF | FF | // |-------------------|---------------------------------------------------------------------------| // | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC | // | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ | mstore(add(ptr, 0x40), bytecodeHash) mstore(add(ptr, 0x20), salt) mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff mstore8(start, 0xff) addr := keccak256(start, 85) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10**64) { value /= 10**64; result += 64; } if (value >= 10**32) { value /= 10**32; result += 32; } if (value >= 10**16) { value /= 10**16; result += 16; } if (value >= 10**8) { value /= 10**8; result += 8; } if (value >= 10**4) { value /= 10**4; result += 4; } if (value >= 10**2) { value /= 10**2; result += 2; } if (value >= 10**1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0); } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@gridexprotocol/core/contracts/interfaces/IWETHMinimum.sol"; import "./interfaces/IPayments.sol"; abstract contract AbstractPayments is IPayments, Context { /// @dev The address of IGridFactory address public immutable gridFactory; /// @dev The address of IWETHMinimum address public immutable weth9; constructor(address _gridFactory, address _weth9) { // AP_NC: not contract require(Address.isContract(_gridFactory), "AP_NC"); require(Address.isContract(_weth9), "AP_NC"); gridFactory = _gridFactory; weth9 = _weth9; } modifier checkDeadline(uint256 deadline) { // AP_TTO: transaction too old require(block.timestamp <= deadline, "AP_TTO"); _; } receive() external payable { // AP_WETH9: not WETH9 require(_msgSender() == weth9, "AP_WETH9"); } /// @inheritdoc IPayments function unwrapWETH9(uint256 amountMinimum, address recipient) public payable override { uint256 balanceWETH9 = IWETHMinimum(weth9).balanceOf(address(this)); // AP_IWETH9: insufficient WETH9 require(balanceWETH9 >= amountMinimum, "AP_IWETH9"); if (balanceWETH9 > 0) { IWETHMinimum(weth9).withdraw(balanceWETH9); Address.sendValue(payable(recipient), balanceWETH9); } } /// @inheritdoc IPayments function sweepToken(address token, uint256 amountMinimum, address recipient) public payable override { uint256 balanceToken = IERC20(token).balanceOf(address(this)); // AP_ITKN: insufficient token require(balanceToken >= amountMinimum, "AP_ITKN"); if (balanceToken > 0) SafeERC20.safeTransfer(IERC20(token), recipient, balanceToken); } /// @inheritdoc IPayments function refundNativeToken() external payable { if (address(this).balance > 0) Address.sendValue(payable(_msgSender()), address(this).balance); } /// @dev Pays the token to the recipient /// @param token The token to pay /// @param payer The address of the payment token /// @param recipient The address that will receive the payment /// @param amount The amount to pay function pay(address token, address payer, address recipient, uint256 amount) internal { if (token == weth9 && address(this).balance >= amount) { // pay with WETH9 Address.sendValue(payable(weth9), amount); IWETHMinimum(weth9).transfer(recipient, amount); } else if (payer == address(this)) SafeERC20.safeTransfer(IERC20(token), recipient, amount); else SafeERC20.safeTransferFrom(IERC20(token), payer, recipient, amount); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; /// @dev Backward compatible EIP-2612 contract definitions. // For more information, please refer to https://eips.ethereum.org/EIPS/eip-2612#backwards-compatibility interface IPermit2612Compatible { function permit( address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s ) external; } /// @dev Base contract for supporting the EIP-2612 specification. /// For more information, please refer to https://eips.ethereum.org/EIPS/eip-2612 abstract contract AbstractSelfPermit2612 { function selfPermit( address token, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external payable { IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s); } function selfPermitIfNecessary( address token, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external payable { if (IERC20(token).allowance(msg.sender, address(this)) < value) IERC20Permit(token).permit(msg.sender, address(this), value, deadline, v, r, s); } function selfPermitCompatible( address token, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external payable { IPermit2612Compatible(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s); } function selfPermitCompatibleIfNecessary( address token, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external payable { if (IERC20(token).allowance(msg.sender, address(this)) < type(uint256).max) IPermit2612Compatible(token).permit(msg.sender, address(this), nonce, expiry, true, v, r, s); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import "@gridexprotocol/core/contracts/interfaces/callback/IGridPlaceMakerOrderCallback.sol"; import "@gridexprotocol/core/contracts/interfaces/IGridParameters.sol"; /// @title The interface for the maker order manager interface IMakerOrderManager is IGridPlaceMakerOrderCallback { struct InitializeParameters { address tokenA; address tokenB; int24 resolution; uint160 priceX96; address recipient; IGridParameters.BoundaryLowerWithAmountParameters[] orders0; IGridParameters.BoundaryLowerWithAmountParameters[] orders1; } struct PlaceOrderParameters { uint256 deadline; address recipient; address tokenA; address tokenB; int24 resolution; bool zero; int24 boundaryLower; uint128 amount; } struct PlaceOrderInBatchParameters { uint256 deadline; address recipient; address tokenA; address tokenB; int24 resolution; bool zero; IGridParameters.BoundaryLowerWithAmountParameters[] orders; } /// @notice Initializes the grid with the given parameters function initialize(InitializeParameters calldata initializeParameters) external payable; /// @notice Creates the grid and initializes the grid with the given parameters function createGridAndInitialize(InitializeParameters calldata initializeParameters) external payable; /// @notice Places a maker order on the grid /// @return orderId The unique identifier of the order function placeMakerOrder(PlaceOrderParameters calldata parameters) external payable returns (uint256 orderId); /// @notice Places maker orders on the grid /// @return orderIds The unique identifiers of the orders function placeMakerOrderInBatch( PlaceOrderInBatchParameters calldata parameters ) external payable returns (uint256[] memory orderIds); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; interface IPayments { /// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. /// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. /// @param amountMinimum The minimum amount of WETH9 to unwrap /// @param recipient The address receiving ETH function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; /// @notice Refunds any native token(e.g. ETH) balance held by this contract to the `msg.sender` /// @dev This method is suitable for the following 2 scenarios: /// 1. When using exactInput, the inputted Ether is not fully consumed due to insufficient liquidity so, /// remaining Ether can be withdrawn through this method /// 2. When using exactOutput, the inputted Ether is not fully consumed because the slippage settings /// are too high, henceforth, the remaining Ether can be withdrawn through this method function refundNativeToken() external payable; /// @notice Transfers the full amount of a token held by this contract to a recipient /// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users /// @param token The contract address of the tokens which will be transferred to the `recipient` /// @param amountMinimum The minimum amount of tokens required for a transfer /// @param recipient The destination address of the tokens function sweepToken(address token, uint256 amountMinimum, address recipient) external payable; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; /// @title The interface for the relative order manager interface IRelativeOrderManager { struct RelativeOrderParameters { uint256 deadline; address recipient; address tokenA; address tokenB; int24 resolution; bool zero; uint128 amount; /// @dev The price delta is the price difference between the order price and the grid price, as a Q64.96. /// Positive values mean the order price is higher than the grid price, and negative values mean the order price is /// lower than the grid price. int160 priceDeltaX96; /// @dev The minimum price of the order, as a Q64.96. uint160 priceMinimumX96; /// @dev The maximum price of the order, as a Q64.96. uint160 priceMaximumX96; } /// @notice Places a relative order /// @param parameters The parameters for the relative order /// @return orderId The unique identifier of the order function placeRelativeOrder(RelativeOrderParameters calldata parameters) external payable returns (uint256 orderId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/Address.sol"; abstract contract Multicall { function multicall(bytes[] calldata data) external payable virtual returns (bytes[] memory results) { results = new bytes[](data.length); unchecked { for (uint256 i = 0; i < data.length; i++) { results[i] = _functionDelegateCall(data[i]); } } return results; } function _functionDelegateCall(bytes memory data) private returns (bytes memory) { // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(this).delegatecall(data); // M_LDCF: low-level delegate call failed return Address.verifyCallResult(success, returndata, "M_LDCF"); } }
{ "optimizer": { "enabled": true, "runs": 100000000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_gridFactory","type":"address"},{"internalType":"address","name":"_weth9","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"components":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"int24","name":"resolution","type":"int24"},{"internalType":"uint160","name":"priceX96","type":"uint160"},{"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"int24","name":"boundaryLower","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct IGridParameters.BoundaryLowerWithAmountParameters[]","name":"orders0","type":"tuple[]"},{"components":[{"internalType":"int24","name":"boundaryLower","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct IGridParameters.BoundaryLowerWithAmountParameters[]","name":"orders1","type":"tuple[]"}],"internalType":"struct IMakerOrderManager.InitializeParameters","name":"parameters","type":"tuple"}],"name":"createGridAndInitialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"gridFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"gridexPlaceMakerOrderCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"int24","name":"resolution","type":"int24"},{"internalType":"uint160","name":"priceX96","type":"uint160"},{"internalType":"address","name":"recipient","type":"address"},{"components":[{"internalType":"int24","name":"boundaryLower","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct IGridParameters.BoundaryLowerWithAmountParameters[]","name":"orders0","type":"tuple[]"},{"components":[{"internalType":"int24","name":"boundaryLower","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct IGridParameters.BoundaryLowerWithAmountParameters[]","name":"orders1","type":"tuple[]"}],"internalType":"struct IMakerOrderManager.InitializeParameters","name":"parameters","type":"tuple"}],"name":"initialize","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"int24","name":"resolution","type":"int24"},{"internalType":"bool","name":"zero","type":"bool"},{"internalType":"int24","name":"boundaryLower","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct IMakerOrderManager.PlaceOrderParameters","name":"parameters","type":"tuple"}],"name":"placeMakerOrder","outputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"int24","name":"resolution","type":"int24"},{"internalType":"bool","name":"zero","type":"bool"},{"components":[{"internalType":"int24","name":"boundaryLower","type":"int24"},{"internalType":"uint128","name":"amount","type":"uint128"}],"internalType":"struct IGridParameters.BoundaryLowerWithAmountParameters[]","name":"orders","type":"tuple[]"}],"internalType":"struct IMakerOrderManager.PlaceOrderInBatchParameters","name":"parameters","type":"tuple"}],"name":"placeMakerOrderInBatch","outputs":[{"internalType":"uint256[]","name":"orderIds","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"int24","name":"resolution","type":"int24"},{"internalType":"bool","name":"zero","type":"bool"},{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"int160","name":"priceDeltaX96","type":"int160"},{"internalType":"uint160","name":"priceMinimumX96","type":"uint160"},{"internalType":"uint160","name":"priceMaximumX96","type":"uint160"}],"internalType":"struct IRelativeOrderManager.RelativeOrderParameters","name":"parameters","type":"tuple"}],"name":"placeRelativeOrder","outputs":[{"internalType":"uint256","name":"orderId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"refundNativeToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","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":"selfPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitCompatible","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"selfPermitCompatibleIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","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":"selfPermitIfNecessary","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountMinimum","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"sweepToken","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountMinimum","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"unwrapWETH9","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"weth9","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c06040523480156200001157600080fd5b5060405162003b4138038062003b41833981016040819052620000349162000119565b81816200004c82620000ed60201b62001b251760201c565b620000865760405162461bcd60e51b815260206004820152600560248201526441505f4e4360d81b60448201526064015b60405180910390fd5b6200009c81620000ed60201b62001b251760201c565b620000d25760405162461bcd60e51b815260206004820152600560248201526441505f4e4360d81b60448201526064016200007d565b6001600160a01b039182166080521660a05250620001519050565b6001600160a01b03163b151590565b80516001600160a01b03811681146200011457600080fd5b919050565b600080604083850312156200012d57600080fd5b6200013883620000fc565b91506200014860208401620000fc565b90509250929050565b60805160a051613977620001ca6000396000818160ff0152818161028c01528181610c6901528181610d9901528181611ff90152818161205c01526120cd0152600081816101b9015281816103860152818161082601528181610b8401528181610f7e0152818161107101526114a501526139776000f3fe6080604052600436106100f75760003560e01c80637400b0f01161008a578063c23e3b3811610059578063c23e3b3814610321578063c2e3140a14610334578063df2ab5bb14610347578063f3995c671461035a57600080fd5b80637400b0f0146102ae5780638f61c9f7146102c1578063a6fcb341146102e1578063ac9650d81461030157600080fd5b806341865270116100c6578063418652701461023e57806342d95cc71461024657806349404b7c1461026757806350879c1c1461027a57600080fd5b806303a7dcdc146101a757806311ba05dd146102055780631872c5a2146102185780632d87f41b1461022b57600080fd5b366101a257337f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16146101a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f41505f574554483900000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b005b600080fd5b3480156101b357600080fd5b506101db7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101a0610213366004612d35565b61036d565b6101a0610226366004612d8f565b610730565b6101a0610239366004612d35565b6107eb565b6101a0610ac6565b610259610254366004612df1565b610ad8565b6040519081526020016101fc565b6101a0610275366004612e04565b610c38565b34801561028657600080fd5b506101db7f000000000000000000000000000000000000000000000000000000000000000081565b6101a06102bc366004612d8f565b610e19565b3480156102cd57600080fd5b506101a06102dc366004612e34565b610f69565b6102f46102ef366004612d35565b610fe5565b6040516101fc9190612eb4565b61031461030f366004612ef8565b6112a4565b6040516101fc9190612fe3565b61025961032f366004613063565b61138e565b6101a0610342366004612d8f565b61185d565b6101a0610355366004613076565b611985565b6101a0610368366004612d8f565b611aa8565b600073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016632ca275c06103b860208501856130b8565b6103c860408601602087016130b8565b6103d860608701604088016130e4565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff938416600482015292909116602483015260020b6044820152606401602060405180830381600087803b15801561044f57600080fd5b505af1158015610463573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104879190613101565b905060008061049c60a08501608086016130b8565b73ffffffffffffffffffffffffffffffffffffffff16146104cc576104c760a08401608085016130b8565b6104ce565b335b90508173ffffffffffffffffffffffffffffffffffffffff1663f8421a31604051806080016040528086606001602081019061050a91906130b8565b73ffffffffffffffffffffffffffffffffffffffff90811682528516602082015260400161053b60a088018861311e565b808060200260200160405190810160405280939291908181526020016000905b8282101561058757610578604083028601368190038101906131e1565b8152602001906001019061055b565b505050918352505060200161059f60c088018861311e565b808060200260200160405190810160405280939291908181526020016000905b828210156105eb576105dc604083028601368190038101906131e1565b815260200190600101906105bf565b505050919092525050604080518082019091528061063461060f60208a018a6130b8565b61061f60408b0160208c016130b8565b61062f60608c0160408d016130e4565b611b41565b81526020013373ffffffffffffffffffffffffffffffffffffffff908116909152604080518351805184166020808401919091528181015185168385015292015160020b606082015292015116608082015260a0016040516020818303038152906040526040518363ffffffff1660e01b81526004016106b5929190613299565b600060405180830381600087803b1580156106cf57600080fd5b505af11580156106e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261072991908101906133e9565b5050505050565b6040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104015b600060405180830381600087803b1580156107cb57600080fd5b505af11580156107df573d6000803e3d6000fd5b50505050505050505050565b600061081d6107fd60208401846130b8565b61080d60408501602086016130b8565b61062f60608601604087016130e4565b9050600061084b7f000000000000000000000000000000000000000000000000000000000000000083611bea565b905060008061086060a08601608087016130b8565b73ffffffffffffffffffffffffffffffffffffffff16146108905761088b60a08501608086016130b8565b610892565b335b90508173ffffffffffffffffffffffffffffffffffffffff1663f8421a3160405180608001604052808760600160208101906108ce91906130b8565b73ffffffffffffffffffffffffffffffffffffffff9081168252851660208201526040016108ff60a089018961311e565b808060200260200160405190810160405280939291908181526020016000905b8282101561094b5761093c604083028601368190038101906131e1565b8152602001906001019061091f565b505050918352505060200161096360c089018961311e565b808060200260200160405190810160405280939291908181526020016000905b828210156109af576109a0604083028601368190038101906131e1565b81526020019060010190610983565b505050505081525060405180604001604052808781526020016109cf3390565b73ffffffffffffffffffffffffffffffffffffffff908116909152604080518351805184166020808401919091528181015185168385015292015160020b606082015292015116608082015260a0016040516020818303038152906040526040518363ffffffff1660e01b8152600401610a4a929190613299565b600060405180830381600087803b158015610a6457600080fd5b505af1158015610a78573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610abe91908101906133e9565b505050505050565b4715610ad657610ad63347611cb5565b565b6000813542811015610b46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f41505f54544f00000000000000000000000000000000000000000000000000006044820152606401610197565b6000610b7b610b5b60608601604087016130b8565b610b6b60808701606088016130b8565b61062f60a08801608089016130e4565b90506000610ba97f000000000000000000000000000000000000000000000000000000000000000083611bea565b9050600080610bbe60408801602089016130b8565b73ffffffffffffffffffffffffffffffffffffffff1614610bee57610be960408701602088016130b8565b610bf0565b335b9050610c2e828483610c0860c08b0160a08c0161345b565b610c1860e08c0160c08d016130e4565b610c296101008d0160e08e01613478565b611e0f565b9695505050505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b158015610cc057600080fd5b505afa158015610cd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf89190613493565b905082811015610d64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f41505f49574554483900000000000000000000000000000000000000000000006044820152606401610197565b8015610e14576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b158015610df257600080fd5b505af1158015610e06573d6000803e3d6000fd5b50505050610e148282611cb5565b505050565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e9060440160206040518083038186803b158015610ea657600080fd5b505afa158015610eba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ede9190613493565b1015610abe576040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104016107b1565b6000610f77828401846134ac565b9050610fa77f00000000000000000000000000000000000000000000000000000000000000008260000151611f6b565b8415610fc1578051516020820151610fc191903388611ff7565b8315610729576107298160000151602001518260200151610fdf3390565b87611ff7565b6060813542811015611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f41505f54544f00000000000000000000000000000000000000000000000000006044820152606401610197565b6000611068610b5b60608601604087016130b8565b905060006110967f000000000000000000000000000000000000000000000000000000000000000083611bea565b90506000806110ab60408801602089016130b8565b73ffffffffffffffffffffffffffffffffffffffff16146110db576110d660408701602088016130b8565b6110dd565b335b90508173ffffffffffffffffffffffffffffffffffffffff1663b703179d60405180606001604052808473ffffffffffffffffffffffffffffffffffffffff1681526020018960a0016020810190611135919061345b565b1515815260200161114960c08b018b61311e565b808060200260200160405190810160405280939291908181526020016000905b8282101561119557611186604083028601368190038101906131e1565b81526020019060010190611169565b505050505081525060405180604001604052808781526020016111b53390565b73ffffffffffffffffffffffffffffffffffffffff908116909152604080518351805184166020808401919091528181015185168385015292015160020b606082015292015116608082015260a0016040516020818303038152906040526040518363ffffffff1660e01b8152600401611230929190613572565b600060405180830381600087803b15801561124a57600080fd5b505af115801561125e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c2e91908101906135ce565b60608167ffffffffffffffff8111156112bf576112bf61318d565b6040519080825280602002602001820160405280156112f257816020015b60608152602001906001900390816112dd5790505b50905060005b828110156113865761136184848381811061131557611315613603565b90506020028101906113279190613632565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061218992505050565b82828151811061137357611373613603565b60209081029190910101526001016112f8565b505b92915050565b60008135428110156113fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f41505f54544f00000000000000000000000000000000000000000000000000006044820152606401610197565b600061140e60e0850160c08601613478565b6fffffffffffffffffffffffffffffffff1611611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f4d4f4d5f41495a000000000000000000000000000000000000000000000000006044820152606401610197565b600061149c610b5b60608601604087016130b8565b905060006114ca7f000000000000000000000000000000000000000000000000000000000000000083611bea565b905060008173ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160806040518083038186803b15801561151457600080fd5b505afa158015611528573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154c9190613697565b50505090506000808760e001602081019061156791906136ff565b60130b1361159857611580610100880160e089016136ff565b61158990613751565b6115939083613790565b6115b3565b6115a9610100880160e089016136ff565b6115b390836137c5565b90506115be81612240565b611624576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f4d4f4d5f504f52000000000000000000000000000000000000000000000000006044820152606401610197565b611636610120880161010089016130b8565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16101580156116ae575061167e610140880161012089016130b8565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1611155b611714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f4d4f4d5f504f52000000000000000000000000000000000000000000000000006044820152606401610197565b600061174f61173a6117258461229a565b61173560a08c0160808d016130e4565b6125a3565b61174a60a08b0160808c016130e4565b6125db565b905061176160c0890160a08a0161345b565b6117df57600061177082612632565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146117ab57816117db565b6117db6117be60a08b0160808c016130e4565b6117c890846137fd565b92508261174a60a08c0160808d016130e4565b9150505b6000806117f260408b0160208c016130b8565b73ffffffffffffffffffffffffffffffffffffffff16146118225761181d60408a0160208b016130b8565b611824565b335b905061185085878361183c60c08e0160a08f0161345b565b868e60c0016020810190610c299190613478565b9998505050505050505050565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152859073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e9060440160206040518083038186803b1580156118ca57600080fd5b505afa1580156118de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119029190613493565b1015610abe576040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e4016107b1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a082319060240160206040518083038186803b1580156119ed57600080fd5b505afa158015611a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a259190613493565b905082811015611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f41505f49544b4e000000000000000000000000000000000000000000000000006044820152606401610197565b8015611aa257611aa2848383612939565b50505050565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e4016107b1565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60408051606081018252600080825260208201819052918101919091528273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161115611b96579192915b60405180606001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018360020b81525090505b9392505050565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610611c2c57600080fd5b8151602080840151604080860151815173ffffffffffffffffffffffffffffffffffffffff95861694810194909452939091169082015260029190910b6060820152611be390608001604051602081830303815290604052805190602001207f884a6891a166f885bf6f0a3b330a25e41d1761a5aa091110a229d9a0e34b2c3660001b85612a0d565b80471015611d1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610197565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611d79576040519150601f19603f3d011682016040523d82523d6000602084013e611d7e565b606091505b5050905080610e14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610197565b60008673ffffffffffffffffffffffffffffffffffffffff1663dd5f8a7b60405180608001604052808873ffffffffffffffffffffffffffffffffffffffff16815260200187151581526020018660020b8152602001856fffffffffffffffffffffffffffffffff1681525060405180604001604052808a8152602001611e933390565b73ffffffffffffffffffffffffffffffffffffffff908116909152604080518351805184166020808401919091528181015185168385015292015160020b606082015292015116608082015260a0016040516020818303038152906040526040518363ffffffff1660e01b8152600401611f0e929190613861565b602060405180830381600087803b158015611f2857600080fd5b505af1158015611f3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f609190613493565b979650505050505050565b33611f768383611bea565b73ffffffffffffffffffffffffffffffffffffffff1614611ff3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f43565f49430000000000000000000000000000000000000000000000000000006044820152606401610197565b5050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480156120525750804710155b1561214f576120817f000000000000000000000000000000000000000000000000000000000000000082611cb5565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b15801561211157600080fd5b505af1158015612125573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214991906138c6565b50611aa2565b73ffffffffffffffffffffffffffffffffffffffff831630141561217d57612178848383612939565b611aa2565b611aa284848484612a37565b60606000803073ffffffffffffffffffffffffffffffffffffffff16846040516121b391906138e3565b600060405180830381855af49150503d80600081146121ee576040519150601f19603f3d011682016040523d82523d6000602084013e6121f3565b606091505b509150915061223882826040518060400160405280600681526020017f4d5f4c4443460000000000000000000000000000000000000000000000000000815250612a95565b949350505050565b6000620f188273ffffffffffffffffffffffffffffffffffffffff831610801590611388575073fff6fbe64b68d618d47c209fe40b0d8ee6e23c9173ffffffffffffffffffffffffffffffffffffffff8316111592915050565b600077ffffffffffffffffffffffffffffffffffffffff00000000602083901b166fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211600190811b92831c9790881196179094179092171790911717176080811061234657607f810383901c9150612350565b80607f0383901b91505b908002607f81811c60ff83811c9190911c800280831c81831c1c800280841c81841c1c800280851c81851c1c800280861c81861c1c800280871c81871c1c800280881c81881c1c800280891c81891c1c8002808a1c818a1c1c8002808b1c818b1c1c8002808c1c818c1c1c8002808d1c818d1c1c8002808e1c9c81901c9c909c1c80029c8d901c9e9d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808f0160401b60c09190911c678000000000000000161760c19b909b1c674000000000000000169a909a1760c29990991c672000000000000000169890981760c39790971c671000000000000000169690961760c49590951c670800000000000000169490941760c59390931c670400000000000000169290921760c69190911c670200000000000000161760c79190911c670100000000000000161760c89190911c6680000000000000161760c99190911c6640000000000000161760ca9190911c6620000000000000161760cb9190911c6610000000000000161760cc9190911c6608000000000000161760cd9190911c66040000000000001617691b13d180eb882abba64281027ffffffffffffffffffffffffffffffffffeb84dbf2a407dd93f221832f996e78b8101608090811d906fd9e63e52eeeb7828cf1af18004b842588301901d600281810b9083900b14612597578873ffffffffffffffffffffffffffffffffffffffff1661256f82612632565b73ffffffffffffffffffffffffffffffffffffffff1611156125915781611850565b80611850565b50979650505050505050565b60008160020b828360020b8560020b816125bf576125bf6138ff565b070160020b816125d1576125d16138ff565b0790920392915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f3d8600284900b12156126125750818101611388565b6206c4f383830160020b131561262b5750808203611388565b5081611388565b60008060008360020b1261264b578262ffffff16612653565b8260020b6000035b905060006001821661267657700100000000000000000000000000000000612688565b6ffff97272373d413259a46990580e213a5b70ffffffffffffffffffffffffffffffffff16905060028216156126bc576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b60048216156126db576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b60088216156126fa576fffcb9843d60f6159c9db58835c9266440260801c5b6010821615612719576fff973b41fa98c081472e6896dfb254c00260801c5b6020821615612738576fff2ea16466c96a3843ec78b326b528610260801c5b6040821615612757576ffe5dee046a99a2a811c461f1969c30530260801c5b6080821615612776576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610100821615612796576ff987a7253ac413176f2b074cf7815e540260801c5b6102008216156127b6576ff3392b0822b70005940c7a398e4b70f30260801c5b6104008216156127d6576fe7159475a2c29b7443b29c7fa6e889d90260801c5b6108008216156127f6576fd097f3bdfd2022b8845ad8f792aa58250260801c5b611000821615612816576fa9f746462d870fdf8a65dc1f90e061e50260801c5b612000821615612836576f70d869a156d2a1b890bb3df62baf32f70260801c5b614000821615612856576f31be135f97d08fd981231505542fcfa60260801c5b618000821615612876576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62010000821615612896576e5d6af8dedb81196699c329225ee6040260801c5b620200008216156128b5576d2216e584f5fa1ea926041bedfe980260801c5b620400008216156128d2576b048a170391f7dc42444e8fa20260801c5b620800008216156128ea5766149b34ee7ac2630260801c5b60008460020b131561292957807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81612925576129256138ff565b0490505b63ffffffff0160201c9392505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e149084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612aae565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611aa29085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161298b565b60608315612aa4575081611be3565b611be38383612bba565b6000612b10826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612bfe9092919063ffffffff16565b805190915015610e145780806020019051810190612b2e91906138c6565b610e14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610197565b815115612bca5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610197919061392e565b60606122388484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051612c3291906138e3565b60006040518083038185875af1925050503d8060008114612c6f576040519150601f19603f3d011682016040523d82523d6000602084013e612c74565b606091505b5091509150611f608783838760608315612d13578251612d0c5773ffffffffffffffffffffffffffffffffffffffff85163b612d0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610197565b5081612238565b6122388383612bba565b600060e08284031215612d2f57600080fd5b50919050565b600060208284031215612d4757600080fd5b813567ffffffffffffffff811115612d5e57600080fd5b61223884828501612d1d565b73ffffffffffffffffffffffffffffffffffffffff81168114612d8c57600080fd5b50565b60008060008060008060c08789031215612da857600080fd5b8635612db381612d6a565b95506020870135945060408701359350606087013560ff81168114612dd757600080fd5b9598949750929560808101359460a0909101359350915050565b60006101008284031215612d2f57600080fd5b60008060408385031215612e1757600080fd5b823591506020830135612e2981612d6a565b809150509250929050565b60008060008060608587031215612e4a57600080fd5b8435935060208501359250604085013567ffffffffffffffff80821115612e7057600080fd5b818701915087601f830112612e8457600080fd5b813581811115612e9357600080fd5b886020828501011115612ea557600080fd5b95989497505060200194505050565b6020808252825182820181905260009190848201906040850190845b81811015612eec57835183529284019291840191600101612ed0565b50909695505050505050565b60008060208385031215612f0b57600080fd5b823567ffffffffffffffff80821115612f2357600080fd5b818501915085601f830112612f3757600080fd5b813581811115612f4657600080fd5b8660208260051b8501011115612f5b57600080fd5b60209290920196919550909350505050565b60005b83811015612f88578181015183820152602001612f70565b83811115611aa25750506000910152565b60008151808452612fb1816020860160208601612f6d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613056577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613044858351612f99565b9450928501929085019060010161300a565b5092979650505050505050565b60006101408284031215612d2f57600080fd5b60008060006060848603121561308b57600080fd5b833561309681612d6a565b92506020840135915060408401356130ad81612d6a565b809150509250925092565b6000602082840312156130ca57600080fd5b8135611be381612d6a565b8060020b8114612d8c57600080fd5b6000602082840312156130f657600080fd5b8135611be3816130d5565b60006020828403121561311357600080fd5b8151611be381612d6a565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261315357600080fd5b83018035915067ffffffffffffffff82111561316e57600080fd5b6020019150600681901b360382131561318657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80356fffffffffffffffffffffffffffffffff811681146131dc57600080fd5b919050565b6000604082840312156131f357600080fd5b6040516040810181811067ffffffffffffffff821117156132165761321661318d565b6040528235613224816130d5565b8152613232602084016131bc565b60208201529392505050565b600081518084526020808501945080840160005b8381101561328e578151805160020b88528301516fffffffffffffffffffffffffffffffff168388015260409096019590820190600101613252565b509495945050505050565b60408152600073ffffffffffffffffffffffffffffffffffffffff8085511660408401528060208601511660608401525060408401516080808401526132e260c084018261323e565b905060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08483030160a085015261331d828261323e565b91505082810360208401526133328185612f99565b95945050505050565b600082601f83011261334c57600080fd5b8151602067ffffffffffffffff808311156133695761336961318d565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156133ac576133ac61318d565b6040529384528581018301938381019250878511156133ca57600080fd5b83870191505b84821015611f60578151835291830191908301906133d0565b600080604083850312156133fc57600080fd5b825167ffffffffffffffff8082111561341457600080fd5b6134208683870161333b565b9350602085015191508082111561343657600080fd5b506134438582860161333b565b9150509250929050565b8015158114612d8c57600080fd5b60006020828403121561346d57600080fd5b8135611be38161344d565b60006020828403121561348a57600080fd5b611be3826131bc565b6000602082840312156134a557600080fd5b5051919050565b600081830360808112156134bf57600080fd5b6040516040810167ffffffffffffffff82821081831117156134e3576134e361318d565b8160405260608412156134f557600080fd5b60a083019350818410818511171561350f5761350f61318d565b50826040528435925061352183612d6a565b91825260208401359161353383612d6a565b82606083015260408501359250613549836130d5565b826080830152808252506060840135915061356382612d6a565b60208101919091529392505050565b6040815273ffffffffffffffffffffffffffffffffffffffff835116604082015260208301511515606082015260006040840151606060808401526135ba60a084018261323e565b905082810360208401526133328185612f99565b6000602082840312156135e057600080fd5b815167ffffffffffffffff8111156135f757600080fd5b6122388482850161333b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261366757600080fd5b83018035915067ffffffffffffffff82111561368257600080fd5b60200191503681900382131561318657600080fd5b600080600080608085870312156136ad57600080fd5b84516136b881612d6a565b60208601519094506136c9816130d5565b604086015190935063ffffffff811681146136e357600080fd5b60608601519092506136f48161344d565b939692955090935050565b60006020828403121561371157600080fd5b81358060130b8114611be357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160130b7fffffffffffffffffffffffff800000000000000000000000000000000000000081141561378757613787613722565b60000392915050565b600073ffffffffffffffffffffffffffffffffffffffff838116908316818110156137bd576137bd613722565b039392505050565b600073ffffffffffffffffffffffffffffffffffffffff8083168185168083038211156137f4576137f4613722565b01949350505050565b60008160020b8360020b60008112817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000183128115161561384057613840613722565b81627fffff01831381161561385757613857613722565b5090039392505050565b73ffffffffffffffffffffffffffffffffffffffff8351168152602083015115156020820152604083015160020b60408201526fffffffffffffffffffffffffffffffff606084015116606082015260a06080820152600061223860a0830184612f99565b6000602082840312156138d857600080fd5b8151611be38161344d565b600082516138f5818460208701612f6d565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b602081526000611be36020830184612f9956fea26469706673582212208158b6338f80e190fddfec90db31f325496320168245428bb4fa775dfccca36464736f6c6343000809003300000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Deployed Bytecode
0x6080604052600436106100f75760003560e01c80637400b0f01161008a578063c23e3b3811610059578063c23e3b3814610321578063c2e3140a14610334578063df2ab5bb14610347578063f3995c671461035a57600080fd5b80637400b0f0146102ae5780638f61c9f7146102c1578063a6fcb341146102e1578063ac9650d81461030157600080fd5b806341865270116100c6578063418652701461023e57806342d95cc71461024657806349404b7c1461026757806350879c1c1461027a57600080fd5b806303a7dcdc146101a757806311ba05dd146102055780631872c5a2146102185780632d87f41b1461022b57600080fd5b366101a257337f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16146101a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f41505f574554483900000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b005b600080fd5b3480156101b357600080fd5b506101db7f00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101a0610213366004612d35565b61036d565b6101a0610226366004612d8f565b610730565b6101a0610239366004612d35565b6107eb565b6101a0610ac6565b610259610254366004612df1565b610ad8565b6040519081526020016101fc565b6101a0610275366004612e04565b610c38565b34801561028657600080fd5b506101db7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b6101a06102bc366004612d8f565b610e19565b3480156102cd57600080fd5b506101a06102dc366004612e34565b610f69565b6102f46102ef366004612d35565b610fe5565b6040516101fc9190612eb4565b61031461030f366004612ef8565b6112a4565b6040516101fc9190612fe3565b61025961032f366004613063565b61138e565b6101a0610342366004612d8f565b61185d565b6101a0610355366004613076565b611985565b6101a0610368366004612d8f565b611aa8565b600073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c16632ca275c06103b860208501856130b8565b6103c860408601602087016130b8565b6103d860608701604088016130e4565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b16815273ffffffffffffffffffffffffffffffffffffffff938416600482015292909116602483015260020b6044820152606401602060405180830381600087803b15801561044f57600080fd5b505af1158015610463573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104879190613101565b905060008061049c60a08501608086016130b8565b73ffffffffffffffffffffffffffffffffffffffff16146104cc576104c760a08401608085016130b8565b6104ce565b335b90508173ffffffffffffffffffffffffffffffffffffffff1663f8421a31604051806080016040528086606001602081019061050a91906130b8565b73ffffffffffffffffffffffffffffffffffffffff90811682528516602082015260400161053b60a088018861311e565b808060200260200160405190810160405280939291908181526020016000905b8282101561058757610578604083028601368190038101906131e1565b8152602001906001019061055b565b505050918352505060200161059f60c088018861311e565b808060200260200160405190810160405280939291908181526020016000905b828210156105eb576105dc604083028601368190038101906131e1565b815260200190600101906105bf565b505050919092525050604080518082019091528061063461060f60208a018a6130b8565b61061f60408b0160208c016130b8565b61062f60608c0160408d016130e4565b611b41565b81526020013373ffffffffffffffffffffffffffffffffffffffff908116909152604080518351805184166020808401919091528181015185168385015292015160020b606082015292015116608082015260a0016040516020818303038152906040526040518363ffffffff1660e01b81526004016106b5929190613299565b600060405180830381600087803b1580156106cf57600080fd5b505af11580156106e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261072991908101906133e9565b5050505050565b6040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104015b600060405180830381600087803b1580156107cb57600080fd5b505af11580156107df573d6000803e3d6000fd5b50505050505050505050565b600061081d6107fd60208401846130b8565b61080d60408501602086016130b8565b61062f60608601604087016130e4565b9050600061084b7f00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c83611bea565b905060008061086060a08601608087016130b8565b73ffffffffffffffffffffffffffffffffffffffff16146108905761088b60a08501608086016130b8565b610892565b335b90508173ffffffffffffffffffffffffffffffffffffffff1663f8421a3160405180608001604052808760600160208101906108ce91906130b8565b73ffffffffffffffffffffffffffffffffffffffff9081168252851660208201526040016108ff60a089018961311e565b808060200260200160405190810160405280939291908181526020016000905b8282101561094b5761093c604083028601368190038101906131e1565b8152602001906001019061091f565b505050918352505060200161096360c089018961311e565b808060200260200160405190810160405280939291908181526020016000905b828210156109af576109a0604083028601368190038101906131e1565b81526020019060010190610983565b505050505081525060405180604001604052808781526020016109cf3390565b73ffffffffffffffffffffffffffffffffffffffff908116909152604080518351805184166020808401919091528181015185168385015292015160020b606082015292015116608082015260a0016040516020818303038152906040526040518363ffffffff1660e01b8152600401610a4a929190613299565b600060405180830381600087803b158015610a6457600080fd5b505af1158015610a78573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610abe91908101906133e9565b505050505050565b4715610ad657610ad63347611cb5565b565b6000813542811015610b46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f41505f54544f00000000000000000000000000000000000000000000000000006044820152606401610197565b6000610b7b610b5b60608601604087016130b8565b610b6b60808701606088016130b8565b61062f60a08801608089016130e4565b90506000610ba97f00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c83611bea565b9050600080610bbe60408801602089016130b8565b73ffffffffffffffffffffffffffffffffffffffff1614610bee57610be960408701602088016130b8565b610bf0565b335b9050610c2e828483610c0860c08b0160a08c0161345b565b610c1860e08c0160c08d016130e4565b610c296101008d0160e08e01613478565b611e0f565b9695505050505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16906370a082319060240160206040518083038186803b158015610cc057600080fd5b505afa158015610cd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf89190613493565b905082811015610d64576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f41505f49574554483900000000000000000000000000000000000000000000006044820152606401610197565b8015610e14576040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b158015610df257600080fd5b505af1158015610e06573d6000803e3d6000fd5b50505050610e148282611cb5565b505050565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523360048201523060248201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e9060440160206040518083038186803b158015610ea657600080fd5b505afa158015610eba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ede9190613493565b1015610abe576040517f8fcbaf0c00000000000000000000000000000000000000000000000000000000815233600482015230602482015260448101869052606481018590526001608482015260ff841660a482015260c4810183905260e4810182905273ffffffffffffffffffffffffffffffffffffffff871690638fcbaf0c90610104016107b1565b6000610f77828401846134ac565b9050610fa77f00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c8260000151611f6b565b8415610fc1578051516020820151610fc191903388611ff7565b8315610729576107298160000151602001518260200151610fdf3390565b87611ff7565b6060813542811015611053576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f41505f54544f00000000000000000000000000000000000000000000000000006044820152606401610197565b6000611068610b5b60608601604087016130b8565b905060006110967f00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c83611bea565b90506000806110ab60408801602089016130b8565b73ffffffffffffffffffffffffffffffffffffffff16146110db576110d660408701602088016130b8565b6110dd565b335b90508173ffffffffffffffffffffffffffffffffffffffff1663b703179d60405180606001604052808473ffffffffffffffffffffffffffffffffffffffff1681526020018960a0016020810190611135919061345b565b1515815260200161114960c08b018b61311e565b808060200260200160405190810160405280939291908181526020016000905b8282101561119557611186604083028601368190038101906131e1565b81526020019060010190611169565b505050505081525060405180604001604052808781526020016111b53390565b73ffffffffffffffffffffffffffffffffffffffff908116909152604080518351805184166020808401919091528181015185168385015292015160020b606082015292015116608082015260a0016040516020818303038152906040526040518363ffffffff1660e01b8152600401611230929190613572565b600060405180830381600087803b15801561124a57600080fd5b505af115801561125e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610c2e91908101906135ce565b60608167ffffffffffffffff8111156112bf576112bf61318d565b6040519080825280602002602001820160405280156112f257816020015b60608152602001906001900390816112dd5790505b50905060005b828110156113865761136184848381811061131557611315613603565b90506020028101906113279190613632565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061218992505050565b82828151811061137357611373613603565b60209081029190910101526001016112f8565b505b92915050565b60008135428110156113fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f41505f54544f00000000000000000000000000000000000000000000000000006044820152606401610197565b600061140e60e0850160c08601613478565b6fffffffffffffffffffffffffffffffff1611611487576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f4d4f4d5f41495a000000000000000000000000000000000000000000000000006044820152606401610197565b600061149c610b5b60608601604087016130b8565b905060006114ca7f00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c83611bea565b905060008173ffffffffffffffffffffffffffffffffffffffff16633850c7bd6040518163ffffffff1660e01b815260040160806040518083038186803b15801561151457600080fd5b505afa158015611528573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154c9190613697565b50505090506000808760e001602081019061156791906136ff565b60130b1361159857611580610100880160e089016136ff565b61158990613751565b6115939083613790565b6115b3565b6115a9610100880160e089016136ff565b6115b390836137c5565b90506115be81612240565b611624576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f4d4f4d5f504f52000000000000000000000000000000000000000000000000006044820152606401610197565b611636610120880161010089016130b8565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16101580156116ae575061167e610140880161012089016130b8565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1611155b611714576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f4d4f4d5f504f52000000000000000000000000000000000000000000000000006044820152606401610197565b600061174f61173a6117258461229a565b61173560a08c0160808d016130e4565b6125a3565b61174a60a08b0160808c016130e4565b6125db565b905061176160c0890160a08a0161345b565b6117df57600061177082612632565b90508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146117ab57816117db565b6117db6117be60a08b0160808c016130e4565b6117c890846137fd565b92508261174a60a08c0160808d016130e4565b9150505b6000806117f260408b0160208c016130b8565b73ffffffffffffffffffffffffffffffffffffffff16146118225761181d60408a0160208b016130b8565b611824565b335b905061185085878361183c60c08e0160a08f0161345b565b868e60c0016020810190610c299190613478565b9998505050505050505050565b6040517fdd62ed3e000000000000000000000000000000000000000000000000000000008152336004820152306024820152859073ffffffffffffffffffffffffffffffffffffffff88169063dd62ed3e9060440160206040518083038186803b1580156118ca57600080fd5b505afa1580156118de573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119029190613493565b1015610abe576040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e4016107b1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8516906370a082319060240160206040518083038186803b1580156119ed57600080fd5b505afa158015611a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a259190613493565b905082811015611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f41505f49544b4e000000000000000000000000000000000000000000000000006044820152606401610197565b8015611aa257611aa2848383612939565b50505050565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018690526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff87169063d505accf9060e4016107b1565b73ffffffffffffffffffffffffffffffffffffffff163b151590565b60408051606081018252600080825260208201819052918101919091528273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161115611b96579192915b60405180606001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018360020b81525090505b9392505050565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610611c2c57600080fd5b8151602080840151604080860151815173ffffffffffffffffffffffffffffffffffffffff95861694810194909452939091169082015260029190910b6060820152611be390608001604051602081830303815290604052805190602001207f884a6891a166f885bf6f0a3b330a25e41d1761a5aa091110a229d9a0e34b2c3660001b85612a0d565b80471015611d1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610197565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114611d79576040519150601f19603f3d011682016040523d82523d6000602084013e611d7e565b606091505b5050905080610e14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610197565b60008673ffffffffffffffffffffffffffffffffffffffff1663dd5f8a7b60405180608001604052808873ffffffffffffffffffffffffffffffffffffffff16815260200187151581526020018660020b8152602001856fffffffffffffffffffffffffffffffff1681525060405180604001604052808a8152602001611e933390565b73ffffffffffffffffffffffffffffffffffffffff908116909152604080518351805184166020808401919091528181015185168385015292015160020b606082015292015116608082015260a0016040516020818303038152906040526040518363ffffffff1660e01b8152600401611f0e929190613861565b602060405180830381600087803b158015611f2857600080fd5b505af1158015611f3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f609190613493565b979650505050505050565b33611f768383611bea565b73ffffffffffffffffffffffffffffffffffffffff1614611ff3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600560248201527f43565f49430000000000000000000000000000000000000000000000000000006044820152606401610197565b5050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480156120525750804710155b1561214f576120817f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc282611cb5565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2169063a9059cbb90604401602060405180830381600087803b15801561211157600080fd5b505af1158015612125573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214991906138c6565b50611aa2565b73ffffffffffffffffffffffffffffffffffffffff831630141561217d57612178848383612939565b611aa2565b611aa284848484612a37565b60606000803073ffffffffffffffffffffffffffffffffffffffff16846040516121b391906138e3565b600060405180830381855af49150503d80600081146121ee576040519150601f19603f3d011682016040523d82523d6000602084013e6121f3565b606091505b509150915061223882826040518060400160405280600681526020017f4d5f4c4443460000000000000000000000000000000000000000000000000000815250612a95565b949350505050565b6000620f188273ffffffffffffffffffffffffffffffffffffffff831610801590611388575073fff6fbe64b68d618d47c209fe40b0d8ee6e23c9173ffffffffffffffffffffffffffffffffffffffff8316111592915050565b600077ffffffffffffffffffffffffffffffffffffffff00000000602083901b166fffffffffffffffffffffffffffffffff811160071b81811c67ffffffffffffffff811160061b90811c63ffffffff811160051b90811c61ffff811160041b90811c60ff8111600390811b91821c600f811160021b90811c918211600190811b92831c9790881196179094179092171790911717176080811061234657607f810383901c9150612350565b80607f0383901b91505b908002607f81811c60ff83811c9190911c800280831c81831c1c800280841c81841c1c800280851c81851c1c800280861c81861c1c800280871c81871c1c800280881c81881c1c800280891c81891c1c8002808a1c818a1c1c8002808b1c818b1c1c8002808c1c818c1c1c8002808d1c818d1c1c8002808e1c9c81901c9c909c1c80029c8d901c9e9d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff808f0160401b60c09190911c678000000000000000161760c19b909b1c674000000000000000169a909a1760c29990991c672000000000000000169890981760c39790971c671000000000000000169690961760c49590951c670800000000000000169490941760c59390931c670400000000000000169290921760c69190911c670200000000000000161760c79190911c670100000000000000161760c89190911c6680000000000000161760c99190911c6640000000000000161760ca9190911c6620000000000000161760cb9190911c6610000000000000161760cc9190911c6608000000000000161760cd9190911c66040000000000001617691b13d180eb882abba64281027ffffffffffffffffffffffffffffffffffeb84dbf2a407dd93f221832f996e78b8101608090811d906fd9e63e52eeeb7828cf1af18004b842588301901d600281810b9083900b14612597578873ffffffffffffffffffffffffffffffffffffffff1661256f82612632565b73ffffffffffffffffffffffffffffffffffffffff1611156125915781611850565b80611850565b50979650505050505050565b60008160020b828360020b8560020b816125bf576125bf6138ff565b070160020b816125d1576125d16138ff565b0790920392915050565b60007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f3d8600284900b12156126125750818101611388565b6206c4f383830160020b131561262b5750808203611388565b5081611388565b60008060008360020b1261264b578262ffffff16612653565b8260020b6000035b905060006001821661267657700100000000000000000000000000000000612688565b6ffff97272373d413259a46990580e213a5b70ffffffffffffffffffffffffffffffffff16905060028216156126bc576ffff2e50f5f656932ef12357cf3c7fdcc0260801c5b60048216156126db576fffe5caca7e10e4e61c3624eaa0941cd00260801c5b60088216156126fa576fffcb9843d60f6159c9db58835c9266440260801c5b6010821615612719576fff973b41fa98c081472e6896dfb254c00260801c5b6020821615612738576fff2ea16466c96a3843ec78b326b528610260801c5b6040821615612757576ffe5dee046a99a2a811c461f1969c30530260801c5b6080821615612776576ffcbe86c7900a88aedcffc83b479aa3a40260801c5b610100821615612796576ff987a7253ac413176f2b074cf7815e540260801c5b6102008216156127b6576ff3392b0822b70005940c7a398e4b70f30260801c5b6104008216156127d6576fe7159475a2c29b7443b29c7fa6e889d90260801c5b6108008216156127f6576fd097f3bdfd2022b8845ad8f792aa58250260801c5b611000821615612816576fa9f746462d870fdf8a65dc1f90e061e50260801c5b612000821615612836576f70d869a156d2a1b890bb3df62baf32f70260801c5b614000821615612856576f31be135f97d08fd981231505542fcfa60260801c5b618000821615612876576f09aa508b5b7a84e1c677de54f3e99bc90260801c5b62010000821615612896576e5d6af8dedb81196699c329225ee6040260801c5b620200008216156128b5576d2216e584f5fa1ea926041bedfe980260801c5b620400008216156128d2576b048a170391f7dc42444e8fa20260801c5b620800008216156128ea5766149b34ee7ac2630260801c5b60008460020b131561292957807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81612925576129256138ff565b0490505b63ffffffff0160201c9392505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610e149084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612aae565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff80851660248301528316604482015260648101829052611aa29085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161298b565b60608315612aa4575081611be3565b611be38383612bba565b6000612b10826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612bfe9092919063ffffffff16565b805190915015610e145780806020019051810190612b2e91906138c6565b610e14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610197565b815115612bca5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610197919061392e565b60606122388484600085856000808673ffffffffffffffffffffffffffffffffffffffff168587604051612c3291906138e3565b60006040518083038185875af1925050503d8060008114612c6f576040519150601f19603f3d011682016040523d82523d6000602084013e612c74565b606091505b5091509150611f608783838760608315612d13578251612d0c5773ffffffffffffffffffffffffffffffffffffffff85163b612d0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610197565b5081612238565b6122388383612bba565b600060e08284031215612d2f57600080fd5b50919050565b600060208284031215612d4757600080fd5b813567ffffffffffffffff811115612d5e57600080fd5b61223884828501612d1d565b73ffffffffffffffffffffffffffffffffffffffff81168114612d8c57600080fd5b50565b60008060008060008060c08789031215612da857600080fd5b8635612db381612d6a565b95506020870135945060408701359350606087013560ff81168114612dd757600080fd5b9598949750929560808101359460a0909101359350915050565b60006101008284031215612d2f57600080fd5b60008060408385031215612e1757600080fd5b823591506020830135612e2981612d6a565b809150509250929050565b60008060008060608587031215612e4a57600080fd5b8435935060208501359250604085013567ffffffffffffffff80821115612e7057600080fd5b818701915087601f830112612e8457600080fd5b813581811115612e9357600080fd5b886020828501011115612ea557600080fd5b95989497505060200194505050565b6020808252825182820181905260009190848201906040850190845b81811015612eec57835183529284019291840191600101612ed0565b50909695505050505050565b60008060208385031215612f0b57600080fd5b823567ffffffffffffffff80821115612f2357600080fd5b818501915085601f830112612f3757600080fd5b813581811115612f4657600080fd5b8660208260051b8501011115612f5b57600080fd5b60209290920196919550909350505050565b60005b83811015612f88578181015183820152602001612f70565b83811115611aa25750506000910152565b60008151808452612fb1816020860160208601612f6d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613056577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452613044858351612f99565b9450928501929085019060010161300a565b5092979650505050505050565b60006101408284031215612d2f57600080fd5b60008060006060848603121561308b57600080fd5b833561309681612d6a565b92506020840135915060408401356130ad81612d6a565b809150509250925092565b6000602082840312156130ca57600080fd5b8135611be381612d6a565b8060020b8114612d8c57600080fd5b6000602082840312156130f657600080fd5b8135611be3816130d5565b60006020828403121561311357600080fd5b8151611be381612d6a565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261315357600080fd5b83018035915067ffffffffffffffff82111561316e57600080fd5b6020019150600681901b360382131561318657600080fd5b9250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b80356fffffffffffffffffffffffffffffffff811681146131dc57600080fd5b919050565b6000604082840312156131f357600080fd5b6040516040810181811067ffffffffffffffff821117156132165761321661318d565b6040528235613224816130d5565b8152613232602084016131bc565b60208201529392505050565b600081518084526020808501945080840160005b8381101561328e578151805160020b88528301516fffffffffffffffffffffffffffffffff168388015260409096019590820190600101613252565b509495945050505050565b60408152600073ffffffffffffffffffffffffffffffffffffffff8085511660408401528060208601511660608401525060408401516080808401526132e260c084018261323e565b905060608501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc08483030160a085015261331d828261323e565b91505082810360208401526133328185612f99565b95945050505050565b600082601f83011261334c57600080fd5b8151602067ffffffffffffffff808311156133695761336961318d565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156133ac576133ac61318d565b6040529384528581018301938381019250878511156133ca57600080fd5b83870191505b84821015611f60578151835291830191908301906133d0565b600080604083850312156133fc57600080fd5b825167ffffffffffffffff8082111561341457600080fd5b6134208683870161333b565b9350602085015191508082111561343657600080fd5b506134438582860161333b565b9150509250929050565b8015158114612d8c57600080fd5b60006020828403121561346d57600080fd5b8135611be38161344d565b60006020828403121561348a57600080fd5b611be3826131bc565b6000602082840312156134a557600080fd5b5051919050565b600081830360808112156134bf57600080fd5b6040516040810167ffffffffffffffff82821081831117156134e3576134e361318d565b8160405260608412156134f557600080fd5b60a083019350818410818511171561350f5761350f61318d565b50826040528435925061352183612d6a565b91825260208401359161353383612d6a565b82606083015260408501359250613549836130d5565b826080830152808252506060840135915061356382612d6a565b60208101919091529392505050565b6040815273ffffffffffffffffffffffffffffffffffffffff835116604082015260208301511515606082015260006040840151606060808401526135ba60a084018261323e565b905082810360208401526133328185612f99565b6000602082840312156135e057600080fd5b815167ffffffffffffffff8111156135f757600080fd5b6122388482850161333b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261366757600080fd5b83018035915067ffffffffffffffff82111561368257600080fd5b60200191503681900382131561318657600080fd5b600080600080608085870312156136ad57600080fd5b84516136b881612d6a565b60208601519094506136c9816130d5565b604086015190935063ffffffff811681146136e357600080fd5b60608601519092506136f48161344d565b939692955090935050565b60006020828403121561371157600080fd5b81358060130b8114611be357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008160130b7fffffffffffffffffffffffff800000000000000000000000000000000000000081141561378757613787613722565b60000392915050565b600073ffffffffffffffffffffffffffffffffffffffff838116908316818110156137bd576137bd613722565b039392505050565b600073ffffffffffffffffffffffffffffffffffffffff8083168185168083038211156137f4576137f4613722565b01949350505050565b60008160020b8360020b60008112817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000183128115161561384057613840613722565b81627fffff01831381161561385757613857613722565b5090039392505050565b73ffffffffffffffffffffffffffffffffffffffff8351168152602083015115156020820152604083015160020b60408201526fffffffffffffffffffffffffffffffff606084015116606082015260a06080820152600061223860a0830184612f99565b6000602082840312156138d857600080fd5b8151611be38161344d565b600082516138f5818460208701612f6d565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b602081526000611be36020830184612f9956fea26469706673582212208158b6338f80e190fddfec90db31f325496320168245428bb4fa775dfccca36464736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
-----Decoded View---------------
Arg [0] : _gridFactory (address): 0x32d1F0Dce675902f89D72251DB4AB1d728efa19c
Arg [1] : _weth9 (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000032d1f0dce675902f89d72251db4ab1d728efa19c
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.