Calling from Contract

Code snippets to user TWAMM

Place long term order

Before calling place long term order, you need to approve tokens once for Vault contract.

import "@balancer-labs/v2-vault/contracts/interfaces/IVault.sol";
import "@balancer-labs/v2-vault/contracts/interfaces/IAsset.sol";

address constant VAULT = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
uint256 constant LONG_TERM_ORDER_JOIN_KIND = 4

function placeLongTermOrder(uint256 poolId, address sender, address recipient, 
                            uint256 tokenIndex, uint256 tokenAmount) internal returns (
                                uint256 orderId
                            ) 
{
    IVault vault = IVault(VAULT);
    
    (IERC20[] memory tokens, , ) = vault.getPoolTokens(poolId);

    // Approve token for transfer to vault    
    IERC20(token).approve(VAULT, tokens[tokenIndex]);

    IVault.JoinPoolRequest memory joinPoolRequest;
    joinPoolRequest = getPlaceLongTermOrderPoolRequest(tokenIndex, tokenAmount, tokens)
    
    // Place long term order request
    vault.joinPool(poolId, sender, recipient, joinPoolRequest);
}

function getPlaceLongTermOrderPoolRequest(IERC20[] memory tokens, uint256 tokenInIndex, 
                                          uint256 tokenOutIndex, uint256 tokenInAmount, 
                                          uint256 numberOfBlockIntervals) returns (
                                              IVault.JoinPoolRequest joinPoolRequest
                                          ) 
{
    bytes memory userData = abi.encode(LONG_TERM_ORDER_JOIN_KIND, tokenInIndex, tokenOutIndex, 
                                       tokenInAmount, numberOfBlockIntervals);
    
    uint256[] memory maxAmountsIn = new uint256[](2);
    for (uint256 i; i < 2; i++) {
        maxAmountsIn[i] = type(uint256).max;
    }
    
    IAsset[] memory assets = new IAsset[](2);
    assets[0] = IAsset(address(tokens[0]))
    assets[1] = IAsset(address(tokens[1]))
    
    bool fromInternalBalance = false;
    
    joinPoolRequest = IVault.JoinPoolRequest(assets, maxAmountsIn, userData, fromInternalBalance)
}

Withdraw long term order

In case the order is not completed when the withdraw long term order is called, partial withdrawal happens.

import "@balancer-labs/v2-vault/contracts/interfaces/IVault.sol";
import "@balancer-labs/v2-vault/contracts/interfaces/IAsset.sol";

address constant VAULT = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
uint256 constant WITHDRAW_LONG_TERM_ORDER_EXIT_KIND = 5

function withdrawLongTermOrder(uint256 poolId, address recipient, uint256 orderId) 
                                internal returns (
                                    uint256 orderId
                                ) 
{
    IVault vault = IVault(VAULT);
    
    (IERC20[] memory tokens, , ) = vault.getPoolTokens(poolId);

    IVault.ExitPoolRequest memory exitPoolRequest;
    exitPoolRequest = getWithdrawLongTermOrderPoolRequest(tokens, orderId)
    
    // Place long term order request
    vault.exitPool(poolId, recipient, recipient, exitPoolRequest);
}

function getWithdrawLongTermOrderPoolRequest(IERC20[] memory tokens, uint256 orderId) returns (
                                                    IVault.ExitPoolRequest exitPoolRequest
                                            ) 
{
    bytes memory userData = abi.encode(WITHDRAW_LONG_TERM_ORDER_EXIT_KIND, orderId);
    
    // Default initiatlized to 0
    uint256[] memory minAmountsOut = new uint256[](2);
    
    IAsset[] memory assets = new IAsset[](2);
    assets[0] = IAsset(address(tokens[0]))
    assets[1] = IAsset(address(tokens[1]))
    
    bool toInternalBalance = false;
    
    exitPoolRequest = IVault.ExitPoolRequest(assets, minAmountsOut, userData, toInternalBalance)
}

Cancel long term order

This is mostly same as withdraw long term order request.

import "@balancer-labs/v2-vault/contracts/interfaces/IVault.sol";
import "@balancer-labs/v2-vault/contracts/interfaces/IAsset.sol";

address constant VAULT = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
uint256 constant CANCEL_LONG_TERM_ORDER_EXIT_KIND = 4

function cancelLongTermOrder(uint256 poolId, address recipient, uint256 orderId) internal returns (
                                uint256 orderId
                            ) 
{
    IVault vault = IVault(VAULT);
    
    (IERC20[] memory tokens, , ) = vault.getPoolTokens(poolId);

    IVault.ExitPoolRequest memory exitPoolRequest;
    exitPoolRequest = getCancelLongTermOrderPoolRequest(tokens, orderId)
    
    // Place long term order request
    vault.exitPool(poolId, recipient, recipient, exitPoolRequest);
}

function getCancelLongTermOrderPoolRequest(IERC20[] memory tokens, uint256 orderId) returns (
                                                IVault.ExitPoolRequest exitPoolRequest
                                           ) 
{
    bytes memory userData = abi.encode(CANCEL_LONG_TERM_ORDER_EXIT_KIND, orderId);
    
    // Default initiatlized to 0
    uint256[] memory minAmountsOut = new uint256[](2);
    
    IAsset[] memory assets = new IAsset[](2);
    assets[0] = IAsset(address(tokens[0]))
    assets[1] = IAsset(address(tokens[1]))
    
    bool toInternalBalance = false;
    
    exitPoolRequest = IVault.ExitPoolRequest(assets, minAmountsOut, userData, toInternalBalance)
}

Last updated