Swap
Let's Swap 0.1 USDC => ETH
Since this is the first section, I'm going to write it out in full, and from add liquidity on, I'm going to keep it simple and easy to understand.
**Always refer Example Codes to see what was the exact implementation of helper functions like toToken, toPoolId, toTokenInfo.
using TokenLib for Token;
/**
if you don't want to import Token lib, you could simply use this snippet instead for Token type conversion.
For ERC20, it's just a bytes32 left padded with 0.
For Eth(Native token), use 0xEEEE..E as token address.
type Token is bytes32;
function toToken(IERC20 tok) pure returns (Token) {
return Token.wrap(bytes32(uint256(uint160(address(tok)))));
}
*/
IVault vault = IVault(0x1d0188c4B276A09366D05d6Be06aF61a73bC7535);
uint8 constant SWAP = 0;
uint8 constant GAUGE = 1;
uint8 constant EXACTLY = 0;
uint8 constant AT_MOST = 1;
uint8 constant ALL = 2;
function swapExample() external {
address usdc = 0x176211869cA2b568f2A7D4EE941E073a821EE1ff;
address vc = 0xcc22F6AA610D1b2a0e89EF228079cB3e1831b1D1;
address eth = address(0);
address usdc_eth_pool = vault.getPair(usdc, eth);
address usdc_eth_lp = usdc_eth_pool;
IERC20(usdc).approve(address(vault), type(uint256).max);
// you can optimize gas by batching operations.
// this example will execute them separately for clarity
//swap usdc->eth
/*
Remember that Execute takes 3 params : Token[], deposit[], Op[].
Let's construct them one by one.
First, deposit[] is rarely used, so you could just set it as a zero array with the same length as Token array.
*/
//Step 1. Prepare Token array
//2 tokens, USDC & ETH are involved in this swap.
Token[] memory tokens = new Token[](2);
//Token constant NATIVE_TOKEN = Token.wrap(0xEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE); //ref: lib/Token.sol
tokens[0] = toToken(IERC20(usdc));
tokens[1] = eth == address(0) ? NATIVE_TOKEN : toToken(IERC20(eth));// =NATIVE_TOKEN for eth
//Step 2. Prepare Op array
/* struct VelocoreOperation {
// 1byte optype(SWAP/STAKE/CONVERT/VOTE/handleUserBalance) + (11bytes 0 padding) + 20bytes related pool address
bytes32 poolId;
// 1byte index at Token[] above + 1 byte amount Type(exactly/at most/vitual balance)
// + (14bytes padding)+ 16bytes int128 desiredAmount(=minimum Amt)
bytes32[] tokenInformations;
//usually empty. ""
bytes data;
} */
// We are doing only one operation here. Swap. So op length is 1.
VelocoreOperation[] memory ops = new VelocoreOperation[](1);
// optype==SWAP, pool=usdc_eth_pool
ops[0].poolId = toPoolId(SWAP,usdc_eth_pool);
ops[0].tokenInformations = new bytes32[](2);
// Index for usdc is 0 at Token[], Exactly 0.1e6 USDC is used. pool receives USDC so amount is positive.
ops[0].tokenInformations[0] = toTokenInfo(0x00,EXACTLY,0.1e6);
// Index for eth is 1 at Token[]. We didn't set slippage here, but you could calculate the minimum amount and use the number instead of 0.
// ETH is expected to flow out of the pool, so the sign of int128 should be negative. if the minimum amount you want is 0.1 eth, use int128(-0.1).
// That's why it's called AT_MOST, not AT_LEAST.
ops[0].tokenInformations[1] = toTokenInfo(0x01,AT_MOST,0);
ops[0].data = "";
//Step 3. execute() !!
return execute(tokens, new int128[](2), ops);
}
Last updated