This guide is to help users remove old positions that they have made through the now deprecated Trident AMM. Adapted from the notes of contributor 0xMaka with some edits.
Approving the Liquidity Token
Before removing the liquidity through the Trident router contract, the users have to approve the Trident router address as a spender for their SLP tokens. As users usually have already done that when trying to remove liquidity through the UI (problems occur with the removing, not with the approval), just check user’s address to be sure the Trident router has been approved. If there is a problem with the approval itself, we have to do the following:
NOTE:
PLEASE KEEP IN MIND THAT ALL VALUES (AMOUNTS, ADDRESSES, ETC..) ARE JUST FOR EXAMPLE. WHEN INTERACTING WITH THE SMART CONTRACTS USERS SHOULD USE THEIR OWN WALLET ADDRESSES, CORRESPONDING CONTRACT ADDRESSES, AND AMOUNT VALUES !!!
- Go to the pool address on the block explorer and select “Write contract” (https://arbiscan.io/address/0x176542be47040929a34591367f243f83c1ee13de#writeContract is the contract for this example's pool)
- Connect your wallet (from the button that says 'Connect to Web3')
- In the first filed enter the Trident router address - On the Arbitrum chain it will be 0xD9988b4B5bBC53A794240496cfA9Bf5b1F8E0523. Each chain will have the router on a different address, so be sure you have the right one. You can see them at https://docs.sushi.com/
- In the second put the amount of SLP owned by the user (or put even higher one) - 5246699295914733 (unit256)
- Values input into smart contracts cannot have decimal points. You will need to convert totals into terms of wei. You can do this with a unit converter on a block explorer.
- Click the 'Write' button. A transaction will be generated in your wallet to approve your liquidity tokens.
Interacting with the Trident Router
- Go to the Trident router address on the block explorer and select “Write contract” (https://arbiscan.io/address/0xd9988b4b5bbc53a794240496cfa9bf5b1f8e0523#writeContract)
- Connect your wallet (from the Connect to Web3 button)
- Scroll down to 3.burnLiquidty
- In the first field 'burnLiquidity' put 0 (it will always be 0)
- In the 'Pool' field put the address of the pair - the example in this case: 0x176542be47040929a34591367f243f83c1ee13de
- In the following 'liquidity', put the amount of liquidity - the example in this case: 5246699295914733
- Then in the 'data' field put the padded destination address and Bento toggle - the example in this case: 0x0000000000000000000000008c14ed4F602ac4d2Be8Ed9c4716307c73e9A83A80000000000000000000000000000000000000000000000000000000000000001
- And in 'minWithdrawals (tuple[])' put - [["0x61de0041bd4c2951b3274028a86daaacc2260949","2306000000000000"],["0x82af49447d8a07e3bd95bd0d56f35241523fbab1","1191000000000000"]] (the addresses of both tokens in that pair and the minimal amounts (in unit256) the user is willing to accept) - min amounts should be at least 0.5% less then the actual amounts.
- After that click 'Write' button to generate your removal transaction.
- *Data consist of the address (usually the user’s address) and the destination (Bento balance or wallet) to where the SLP should be unwound. Both (address and destination) consist of 64 characters, so 0s where there is no value, and add 0x at the front. The first 64 characters (after 0x) represent the users address (but without 0x). In this case our users address is 0x8c14ed4F602ac4d2Be8Ed9c4716307c73e9A83A8. So we take 8c14ed4F602ac4d2Be8Ed9c4716307c73e9A83A8 (40 characters) and add 24 zeros to the left. Destination is determined by the last digit in the data - 0 for unwinding in BentoBox, 1 for unwinding to wallet. So we take 0 or 1 and add 63 zeros to the left. Combine both (address and destination) and add 0x to the left.
- **First value is the address of token0, the second address, of token1. You can find which is token0, and which is token1 via the pool contract with a block explorer (provided the pool contracts are verified).
For some tokens with reverting transfer functions, withdrawing to wallet will not work. With Trident, this can be worked around via taking advantage of the way Bento can internally shift token balances, without calling the tokens broken transfer function. In this case unwind to the user’s BentoBox balance, then the user may withdraw the token that does not have a broken transfer to their wallet. i.e. The token of value be it WETH, USDT, USDC etc.
NOTE: Sending your asset to the BentoBox can be preferred depending on what tokens you are removing, as avoids the potential for any secondary issue with the token that could block withdrawl. This would be a rare occurrence. In most cases you'll want to go directly to the wallet.
Withdrawing from BentoBox
If you decide to send your asset to the BentoBox, we can remove it from the block explorer as well. On the Write tab go 17.withdraw. Set the '_token(address)' as the contract address of the token you want to withdraw, the 'to(address)' and 'from(address)' as yours, and the amount is equal to the balance you are trying to remove for the token. The share value will always be 0. To find the precise exact amount you can query the BentoBox contract on the Read tab under function 2.balanceOf. Just plug in the token address for the first field, and the user address for the second.
You can see the BentoBox contract on Arbitrum here. Contract addresses are available in documentation.
If the transaction cost shown in the wallet is abnormally high (like 1+ ETH) there is some problem. The user should check that there are no spaces in front/after some of the values they entered. Also check if the token addresses positions correspond to the sequence - token0 address should be the first one and token1 address should be the second one. If everything is alright with the inputs, but your wallet still gives high transaction cost or throw some other error, you can simulate the transaction on Tenderly and try to figure what the exact problem is.
Simulating a Transaction on Tenderly
On Tenderly the inputs are pretty much the same, but we first have to specify the contract address (Trident router) and blockchain (Arbitrum). Click on “or Use Fetched Contract ABI” and select “3.burnLiquidity” function from the drop down menu:
Then just put all the data - same as on the contract example (without the first 0), just minWithdrawals can be shown like this:
[{ "token":"0x61de0041bd4c2951b3274028a86daaacc2260949", "amount":"0" }, { "token":"0x82af49447d8a07e3bd95bd0d56f35241523fbab1", "amount":"0" }]
*Here the min amounts are set to 0 as this is the best way to check if the problem is with slippage or if it is something else. If the sim is successful with 100% slippage (0 min amounts), then start playing with the numbers till find the minimum slippage that works.
Don’t forget to put user’s address in the “From” field (on the right).
Note for Rescues:
- For Trident there is a dedicated function for this. Anyone can do it so there is not much time, but if you manage to catch it: Under function 16. sweep(), input 0 for the payable amount, enter the address of the stuck asset for "token" (zero address if it's eth that is stuck). Enter stuck balance for "amount", and destination EAO for "address" (wallet of user or guardian). Enter 0 for "onBento"
Exchange | Furo | Docs | Discord | Twitter | Telegram | Newsletter | YouTube | Github