Open a Position
The openPosition function is used to open a new farming position. This function requires, as input, the FarmingPositionRequest struct:
1
function openPosition(FarmingPositionRequest memory request) public override payable activeSetupOnly(request.setupIndex) returns(uint256 positionId) {
Copied!
At the moment of creation, a positionID that represents the position is generated:
1
positionId = uint256(keccak256(abi.encode(uniqueOwner);
Copied!
Each generated id is encoded with the uniqueOwner (owner position) address. This means that each address can correspond to one and only one position within each setup; a single address cannot have multiple positions in a setup.
A user can also open a position for another address. In this case, the uniqueOwner is not the msg.sender, but rather the address passed in the FarmingPositionRequest:
1
address uniqueOwner = (request.positionOwner != address(0)) ? request.positionOwner : msg.sender;
Copied!
Initial liquidity is transferred from the user to the contract and added to the setup via the _addLiquidity function, which calculates the amount of inserted liquidity (liquidityAmount).
1
uint128 liquidityAmount = _addLiquidity(request.setupIndex, request);
Copied!
When the first user opens a position in the setup, the _addLiquidity function mints the NFT, using the parameters previously passed by the host at the moment of setup creation. See here for more details.
(_addLiquidity can then call the increaseLiquidity method of INonfungiblePositionManager).
1
data[0] = abi.encodeWithSelector(nonfungiblePositionManager.increaseLiquidity.selector, abi.encode(INonfungiblePositionManager.IncreaseLiquidityParams({
2
tokenId: _setups[request.setupIndex].objectId,
3
amount0Desired: request.amount0,
4
amount1Desired: request.amount1,
5
amount0Min: 1,
6
amount1Min: 1,
7
deadline: block.timestamp + 10000
8
})));
9
(liquidityAmount,,) = abi.decode(IMulticall(address(nonfungiblePositionManager)).multicall{ value : ethValue }(data)[0], (uint128, uint256, uint256));
Copied!
At this point, the FarmingPosition struct for the created position is populated as follow:
1
_positions[positionId] = FarmingPosition({ uniqueOwner: uniqueOwner, setupIndex : request.setupIndex, liquidityPoolTokenAmount: liquidityPoolData.amount, mainTokenAmount: mainTokenAmount, reward: reward, lockedRewardPerBlock: lockedRewardPerBlock, creationBlock: block.number
Copied!
Creating a position increases the number of positions within a specific setup by one, given by:
1
mapping(uint256 => uint256) private _setupPositionsCount;
Copied!
1
_setupPositionsCount[request.setupIndex] += 1
Copied!
Copy link