Typescript Examples for Integration
import { solidityPack, parseEther } from "ethers/lib/utils";
import { BigNumber } from "ethers";
export default async function (hre) {
const getContractAt = hre.ethers.getContractAt;
const vault = await getContractAt("IVault", "0x5BA1C526b79bA08668fa23733E762a2579058697");
const factory = await getContractAt("ConstantProductPoolFactory", "0xb4e79Fc4F09f8126c1a5a862DA536daBEf455b6f");
const toToken = (spec: string, id, addr: string) =>
solidityPack(
["uint8", "uint88", "address"],
[["erc20", "erc721", "erc1155"].indexOf(spec), id, addr]
)
const poolId = (i, poolAddress: string) =>
solidityPack(
["bytes1", "uint88", "address"],
[i, 0, poolAddress]
)
const INT128_MAX = ethers.BigNumber.from("170141183460469231731687303715884105727");
const tokenInformation = (index: number, amountType: string, amount) =>
solidityPack(["uint8", "uint8", "uint112", "int128"], [
index,
["exactly", "at most", "all", "flashloan"].indexOf(amountType),
0,
amount
]
)
const compileAndExecute = (value, ops) => {
const tokenRef = [...new Set(ops.flatMap(x => x[1].map(i => i[0])))].sort();
return vault.execute([
tokenRef,
(new Array(tokenRef.length)).fill(0),
ops.map(op => ({
poolId: op[0],
tokenInformations: op[1].map(i => tokenInformation(tokenRef.indexOf(i[0]), i[1], i[2])).sort(),
data: []
}))
, { value }
])
}
const vevc_address = "0x1b187693Aa0D260896a804aEe1816eC4ACE56257";
const vc = toToken("erc20", 0, "0xB0B88DF91c5f1E48854225a076AA39f0933Ea2F5");
const vevc = toToken("erc20", 0, "0x1b187693Aa0D260896a804aEe1816eC4ACE56257");
const usdc = toToken("erc20", 0, "0x699a9c41da7721cb53eb99de3fba2a5a6165f711");
const dai = toToken("erc20", 0, "0x342712712a2e16b31761291bf1931f5eba2d928d");
const eth = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
const INT128_MAX = BigNumber.from("170141183460469231731687303715884105727");
const usdc_eth_pool = await factory.pools(eth, usdc);
const vc_eth_pool = await factory.pools(eth, vc);
const dai_eth_pool = await factory.pools(eth, dai);
const usdc_eth_lp = toToken('ERC20', 0, usdc_eth_pool);
// swap usdc -> eth, exact in
await compileAndExecute(0, [
[poolId(0, usdc_eth_pool), [
[usdc, "exactly", parseEther("100")],
[eth, "at most", parseEther("-0.001")],
]]
])
// swap usdc -> eth, exact out
await compileAndExecute(0, [
[poolId(0, usdc_eth_pool), [
[usdc, "at most", parseEther("100")],
[eth, "exactly", parseEther("-0.001")],
]]
])
// swap usdc -> eth -> dai, exact in
await compileAndExecute(0, [
[poolId(0, usdc_eth_pool), [
[usdc, "exactly", parseEther("100")],
[eth, "at most", INT128_MAX]
]],
[poolId(0, dai_eth_pool), [
[eth, "all", INT128_MAX],
[dai, "at most", parseEther("-99")],
]]
])
// swap usdc -> eth -> dai, exact out
await compileAndExecute(0, [
[poolId(0, dai_eth_pool), [
[eth, "at most", INT128_MAX],
[dai, "exactly", parseEther("-99")],
]],
[poolId(0, usdc_eth_pool), [
[usdc, "at most", parseEther("100")],
[eth, "all", INT128_MAX]
]]
])
// swap eth -> dai, exact in
await compileAndExecute(parseEther("0.001"), [
[poolId(0, dai_eth_pool), [
[eth, "all", INT128_MAX],
[dai, "at most", parseEther("-99")],
]]
])
// swap eth -> dai, exact out, remaining eth will be refunded
await compileAndExecute(parseEther("0.001"), [
[poolId(0, dai_eth_pool), [
[eth, "at most", INT128_MAX],
[dai, "exactly", parseEther("-99")],
]]
])
// add liquidity and stake usdc-eth == "buying lp token and paying usdc and eth"
await compileAndExecute(parseEther("0.001"), [
[poolId(0, usdc_eth_pool), [ // deposit lp
[eth, "all", INT128_MAX],
[usdc, "exactly", parseEther("100")],
[usdc_eth_lp, "at most", 0]
]],
[poolId(1, usdc_eth_pool), [ // stake
[usdc_eth_lp, "all", INT128_MAX]
]]
])
// add liquidity and stake usdc-eth, using single token
await compileAndExecute(0, [
[poolId(0, usdc_eth_pool), [ // deposit lp
[usdc, "exactly", parseEther("100")],
[usdc_eth_lp, "at most", 0]
]],
[poolId(1, usdc_eth_pool), [ // stake
[usdc_eth_lp, "all", INT128_MAX],
[vc, "at most", 0] // vc must be included to receive emissions. it will revert otherwise
]]
])
// harvest vc
await compileAndExecute(0, [
[poolId(1, usdc_eth_pool), [
[vc, "at most", 0] // vc must be included to receive emissions. it will revert otherwise
]],
])
// harvest -> swap -> compound
await compileAndExecute(0, [
[poolId(1, usdc_eth_pool), [ //harvest
[vc, "at most", 0] // vc must be included to receive emissions. it will revert otherwise
]],
[poolId(0, vc_eth_pool), [ // swap
[vc, "all", INT128_MAX],
[eth, "at most", 0],
]],
[poolId(0, usdc_eth_pool), [ // deposit lp
[eth, "all", INT128_MAX],
[usdc_eth_lp, "at most", 0]
]],
[poolId(1, usdc_eth_pool), [ // stake
[usdc_eth_lp, "all", INT128_MAX],
[vc, "at most", 0] // vc must be included to receive emissions. it will revert otherwise
]]
])
// unstake and remove liquidity to usdc
let stakedAmount = (await (await getContractAt("IGauge", usdc_eth_pool)).stakedTokens("0xmy_address"))[0]
await compileAndExecute(0, [
[poolId(1, usdc_eth_pool), [ // unstake
[usdc_eth_lp, "exactly", stakedAmount.neg()],
[vc, "at most", 0] // vc must be included to receive emissions. it will revert otherwise
]],
[poolId(0, usdc_eth_pool), [ // remove lp
[usdc, "at most", 0],
//[eth, "at most", 0], // uncomment to receive both eth and usdc in proportion
[usdc_eth_lp, "all", INT128_MAX]
]],
])
// lock vc
await compileAndExecute(0, [
[poolId(0, vevc_address), [
[vc, "exactly", parseEther("123")],
[vevc, "at most", 0],
]],
])
// vote
await compileAndExecute(0, [
[poolId(4, usdc_eth_pool), [
[vevc, "exactly", parseEther("123")],
]],
])
// unvote
await compileAndExecute(0, [
[poolId(4, usdc_eth_pool), [
[vevc, "exactly", parseEther("-123")],
]],
])
}
Github repo : https://github.com/velocore/velocore-contracts
Last updated