Perform a Dual Investment Withdrawal
Executing a Dual Investment Withdrawal: Two Approaches
Once the lock time concludes, you can withdraw your dual investment position to reclaim your tokens. There are two methods available for initiating a withdrawal, each with its own distinct advantages. The first method involves direct interaction with the Pair contract, while the second utilizes the Router contract. The primary distinction lies in the fact that the second method can facilitate the withdrawal of ETH, wherein the Router converts ETH to WETH before executing the actual withdraw. Additionally, the Router supports withdrawMultiPositions, enabling users to withdraw their positions in a single transaction. This section will provide guidance on both options.
1. Direct Withdraw within Pair Contract
You can simply call withdraw to withdraw your dual investment position and receive either one of token0 or token1.
// Pair.sol
function withdraw(
uint index,
address to) external lock returns (uint token0Amt, uint token1Amt)Parameters:
index: Index of thenoteowned by user.to: Address to receive the redeemed token0 or token1.
Return Values:
token0Amt: Amount of token0 withdrawn.token1Amt: Amount of token1 withdrawn.
Alternatively, you can withdraw a position on behalf of another address, granted approval by the respective address. In this scenario, the owner of the position needs to invoke the setApprovalForAll function to approve your address for position withdrawal. Subsequently, you can utilize the withdrawFrom function to withdraw their position on their behalf. While originally designed for the Router to manage dual investment positions on behalf of users, you can also employ this function for other purposes as necessary.
// Pair.sol
function setApprovalForAll(
address operator,
bool approved) externalParameters:
operator: Address of the operator.approved: Whether the operator is approved or not.
Parameters:
from: Address of the user who owns the position.index: Index of the note.to: Address to receive the redeemed token0 or token1.
Return Value:
token0Amt: Amount of token0 withdrawn.token1Amt: Amount of token1 withdrawn.
Set Up your Contract
Declare the solidity version used to compile the contract.
Import the IPair interface.
Write your own contract, here we name it
MyWithdrawTest.
2. Withdraw through Router Contract
Alternatively, you have the option to initiate a withdrawal through the Router contract. It's important to note that as the Router will be withdrawing the position on your behalf, you need to sign a signature and pre-approve the router for position withdrawal by calling setApprovalForAllWithSig for the pair. Details regarding the signature process will be explained later. Now, let's examine the withdrawal functions below.
withdraw
Parameters:
pair: The address of a specific pair contract.index: Index of the note to withdraw.to: Address that will receive either token0 or token1.
Return Value:
token0Amt: Amount of token0 withdrawn.token1Amt: Amount of token1 withdrawn.
withdrawETH
The withdrawETH function is specifically crafted for scenarios where either token0 or token1 in the pair is WETH. This is because the Router will handle the conversion of your WETH to ETH and subsequently return it to you. If you opt for the regular withdrawal, you would receive WETH instead of ETH.
Parameters:
pair: The address of a specific pair contract.index: Index of the note to withdraw.to: Address that will receive either token0 or token1 (One of them would be ETH).
Return Value:
token0Amt: Amount of token0 withdrawn.token1Amt: Amount of token1 withdrawn.
withdrawMultiPositions
If you find yourself needing to withdraw multiple positions and prefer not to do so individually, employing the withdrawMultiPositions function is an efficient approach. This function enables you to withdraw all your positions across various pairs in a single transaction.
Parameters:
pairs: Array ofPaircontract addresses.indexes: Array of index of the note to withdraw.tos: Array of address that will receive either token0 or token1.
Return Values:
token0Amounts: Array of amount of token0 withdrawn.token1Amounts: Array of amount of token1 withdrawn.
Approve Router for withdrawal with signature
Regardless of whether you opt for withdraw, withdrawETH, or withdrawMultiPositions, it's essential to pre-approve the Router for withdrawal on your behalf using setApprovalForAllWithSig. To illustrate, consider the following scenario: A user Alice intends to withdraw three positions with note IDs 23 and 106 in Pair 1, and note ID 14 in Pair 2. The flow chart below outlines the process:

Highlighting a crucial detail, we implement EIP-712, a standard for hashing and signing typed structured data, in our approval process. The provided code snippets below will demonstrate how to utilize the Foundry library to simulate signing that aligns with the EIP-712 standard.
Set Up your Contract
Declare the solidity version used to compile the contract.
Import IRouter interface.
Last updated