First, declare the solidity version used to compile the contract. If needed (if you are using older versions of solidity) add abicoder v2 to allow arbitrary nested arrays and structs to be encoded and decoded in calldata, a feature that we use when transacting with a pool.
Then, create a contract called LiquidityExamples and inherit both IERC721Receiver and LiquidityManagement.
For this case, we've chosen to hardcode the token contract addresses. Most likely, you would use an input parameter for this in production, allowing you to change the pools and tokens you are interacting with on a per-transaction basis.
contractLiquidityExamplesisIERC721Receiver, LiquidityManagement {addresspublicconstant DAI =0x6B175474E89094C44Da98b954EedeAC495271d0F;addresspublicconstant USDC =0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
Declare an immutable public variable nonfungiblePositionManager of type INonfungiblePositionManager.
To allow deposits of ERC721 expressions of liquidity, create a struct called Deposit, a mapping of uint256 to the Deposit struct, then declare that mapping as a public variable deposits.
Declare the constructor here, which is executed once when the contract is deployed. Our constructor hard codes the address of the non-fungible position manager interface, router, and the periphery immutable state constructor, which requires the factory, pool deployer and the address of WMATIC.
The from identifier may be omitted because it is not used.
functiononERC721Received(address operator,address,uint256 tokenId,bytescalldata ) externaloverridereturns (bytes4) {// get position information_createDeposit(operator, tokenId);returnthis.onERC721Received.selector; }
Creating a Deposit
To add a Deposit instance to the deposits mapping, create an internal function called _createDeposit that destructures the positions struct returned by positions in nonfungiblePositionManager.sol. Pass the relevant variables token0, token1 and liquidity to the deposits mapping.
function_createDeposit(address owner,uint256 tokenId) internal { (,,address token0,address token1,,,uint128 liquidity,,,, ) = nonfungiblePositionManager.positions(tokenId);// set the owner and data for position// operator is msg.sender deposits[tokenId] =Deposit({owner: owner, liquidity: liquidity, token0: token0, token1: token1}); }
The Full Contract Setup
// SPDX-License-Identifier: GPL-2.0-or-laterpragmasolidity =0.8.20;import'@cryptoalgebra/integral-core/contracts/interfaces/IAlgebraPool.sol';import'@cryptoalgebra/integral-core/contracts/libraries/TickMath.sol';import'@cryptoalgebra/integral-periphery/contracts/libraries/TransferHelper.sol';import'@cryptoalgebra/integral-periphery/contracts/interfaces/INonfungiblePositionManager.sol';import'@cryptoalgebra/integral-periphery/contracts/base/LiquidityManagement.sol';import'@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';contractLiquidityExamplesisIERC721Receiver, LiquidityManagement {addresspublicconstant DAI =0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063;addresspublicconstant USDC =0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174; INonfungiblePositionManager publicimmutable nonfungiblePositionManager;/// @notice Represents the deposit of an NFTstructDeposit {address owner;uint128 liquidity;address token0;address token1; }/// @dev deposits[tokenId] => Depositmapping(uint256 tokenId => Deposit) public deposits;constructor(INonfungiblePositionManager_nonfungiblePositionManager,address_factory,address_WMATIC,address_poolDeployer ) PeripheryImmutableState(_factory, _WMATIC, _poolDeployer) { nonfungiblePositionManager = _nonfungiblePositionManager; }// Implementing `onERC721Received` so this contract can receive custody of erc721 tokensfunctiononERC721Received(address operator,address,uint256 tokenId,bytescalldata ) externaloverridereturns (bytes4) {// get position information_createDeposit(operator, tokenId);returnthis.onERC721Received.selector; }function_createDeposit(address owner,uint256 tokenId) internal { (,,address token0,address token1,,,uint128 liquidity,,,, ) = nonfungiblePositionManager.positions(tokenId);// set the owner and data for position// operator is msg.sender deposits[tokenId] =Deposit({owner: owner, liquidity: liquidity, token0: token0, token1: token1}); }}