Frontend Integration

Add Liquidity to a setup in a Farming Contract starting from Ethereum in just one transaction

var voidEthereumAddress = "0x0000000000000000000000000000000000000000";
var prestoAddress = "0x3660c73E030C497cccbE8aaabdc7431fAEB6E495";
var farmingPrestoAddress = "0xE3eFf2b5e9B13910ECb4332c478380C485c37757";
var farmingPresto = new web3.eth.Contract(abis.FarmingPrestoABI, farmingPrestoAddress);

var farmingContractAddress = "0x8EAC3aCd75188C759E0Db3DFa59367acDe2BbBe8";
var farmingContract = new web3.eth.Contract(abis.FarmMainABI, farmingContractAddress);
var setup = (await farmingContract.methods.setup(0).call());
var setupInfo = setup[0];
setup = setup[1];
var amm = new web3.eth.Contract(abis.AMMABI, setupInfo.ammPlugin);
var ethereumAddress = (await amm.methods.data().call())[0];
var tokenAddresses = (await amm..methods.byLiquidityPool(setupInfo.liquidityPoolAddress))[2];

var tokens = [];
for(var address of tokenAddresses) {
    var contract = new web3.eth.Contract(abis.ERC20ABI, address);
    tokens.push({
        address,
        contract,
        name : await contract.methods.name().call(),
        symbol : await contract.methods.symbol().call(),
        decimals : await contract.methods.decimals().call()
    });
}

var lpDecimals = await new web3.eth.Contract(abis.ERC20ABI, setupInfo.liquidityPoolAddress).methods.decimals().call();

var mainTokenIndex = tokenAddresses.indexOf(info.mainTokenAddress);

function normalizeValue(amount, decimals) {
    return web3.utils.toBN(amount).mul(web3.utils.toBN(10 ** (18 - decimals))).toString();
}

async function calculateBestLP(firstToken, secondToken, firstDecimals, secondDecimals, hf) {

    var data = (await amm.methods.byTokens([ethereumAddress, firstToken]).call());
    
    var liquidityPoolAddress = data[2];
    
    if (liquidityPoolAddress === voidEthereumAddress) {
        return {};
    }

    var mainTokenIndex = data[3].indexOf(firstToken);
    var middleTokenIndex = data[3].indexOf(ethereumAddress);

    var mainAmount = parseInt(normalizeValue(data[1][mainTokenIndex], firstDecimals));
    var middleTokenAmount = parseInt(normalizeValue(data[1][middleTokenIndex], 18));

    var constant = mainAmount * middleTokenAmount;

    var newMiddleTokenAmount = middleTokenAmount + parseInt(normalizeValue(halfValue, 18));

    var newMainAmount = constant / newMiddleTokenAmount;

    var mainReceived = mainAmount - newMainAmount;

    var firstTokenEthLiquidityPoolAddress = liquidityPoolAddress;
    var token0Value = (await amm.methods.getSwapOutput(ethereumAddress, hf || halfValue, [liquidityPoolAddress], [firstToken]).call())[1];

    var ratio = newMainAmount / mainAmount;

    if (!hf) {
        return await calculateBestLP(firstToken, secondToken, firstDecimals, secondDecimals, halfValue = window.numberToString(window.formatNumber(halfValue) * ratio).split('.')[0])
    }

    var token1Value = (await ammContract.methods.byTokenAmount(liquidityPool, firstToken, token0Value).call());
    var lpAmount = token1Value[0];
    token1Value = token1Value[1][token1Value[2].indexOf(secondToken)];

    lpAmount = window.numberToString(parseInt(lpAmount) / ratio).split('.')[0];
    token1Value = window.numberToString(parseInt(token1Value) / ratio).split('.')[0];

    const updatedFirstTokenAmount = parseInt(normalizeValue(token0Value, firstDecimals));
    const updatedSecondTokenAmount = parseInt(normalizeValue(token1Value, secondDecimals));

    liquidityPoolAddress = (await amm.methods.byTokens([ethereumAddress, secondToken]).call())[2];
    var secondTokenEthLiquidityPoolAddress = liquidityPoolAddress;
    var token1ValueETH = "0";
    if (secondTokenEthLiquidityPoolAddress !== window.voidEthereumAddress) {
        token1ValueETH = (await amm.methods.getSwapOutput(secondToken, token1Value, [liquidityPoolAddress], [ethereumAddress]).call())[1];
    }

    return { lpAmount, updatedFirstTokenAmount, updatedSecondTokenAmount, token0Value, token1Value, token1ValueETH, firstTokenEthLiquidityPoolAddress, secondTokenEthLiquidityPoolAddress };
}

var bestLP = await calculateBestLP(tokens[0].address, tokens[1].address, tokens[0].decimals, tokens[1].decimals);

var lpAmount = bestLP.lpAmount;
var firstTokenAmount = bestLP.token0Value;
var secondTokenAmount = bestLP.token1Value;
var firstTokenETH = halfValue;
var secondTokenETH = bestLP.token1ValueETH;
var token0EthLiquidityPoolAddress = bestLP.firstTokenEthLiquidityPoolAddress;
var token1EthLiquidityPoolAddress = bestLP.secondTokenEthLiquidityPoolAddress;

if (tokens[0].address === ethereumAddress || !lpAmount || (bestLP.updatedSecondTokenAmount > bestLP.updatedFirstTokenAmount)) {
    bestLP = await calculateBestLP(tokens[1].address, tokens[0].address, tokens[1].decimals, tokens[0].decimals);

    lpAmount = bestLP.lpAmount;
    firstTokenAmount = bestLP.token1Value;
    secondTokenAmount = bestLP.token0Value;
    firstTokenETH = bestLP.token1ValueETH;
    secondTokenETH = halfValue;
    token0EthLiquidityPoolAddress = bestLP.secondTokenEthLiquidityPoolAddress;
    token1EthLiquidityPoolAddress = bestLP.firstTokenEthLiquidityPoolAddress;
}

var operations = [];

token0EthLiquidityPoolAddress !== window.voidEthereumAddress && operations.push({
    inputTokenAddress: ethereumAddress,
    inputTokenAmount: firstTokenETH,
    ammPlugin: amm.options.address,
    liquidityPoolAddresses: [token0EthLiquidityPoolAddress],
    swapPath: [tokens[0].address],
    enterInETH: true,
    exitInETH: false,
    receivers: [farmingPresto.options.address],
    receiversPercentages: []
});

token1EthLiquidityPoolAddress !== window.voidEthereumAddress && operations.push({
    inputTokenAddress: ethereumAddress,
    inputTokenAmount: secondTokenETH,
    ammPlugin: amm.options.address,
    liquidityPoolAddresses: [token1EthLiquidityPoolAddress],
    swapPath: [tokens[1].address],
    enterInETH: true,
    exitInETH: false,
    receivers: [farmingPresto.options.address],
    receiversPercentages: []
});

var ethValue = 0;
token0EthLiquidityPoolAddress !== voidEthereumAddress && (ethValue = web3.utils.toBN(ethValue).add(web3.utils.toBN(firstTokenETH)).toString());
token1EthLiquidityPoolAddress !== voidEthereumAddress && (ethValue = web3.utils.toBN(ethValue).add(web3.utils.toBN(secondTokenETH)).toString());
setupInfo.involvingETH && tokens[0].address === ethereumAddress && (ethValue = web3.utils.toBN(ethValue).add(web3.utils.toBN(firstTokenAmount)).toString());
setupInfo.involvingETH && tokens[1].address === ethereumAddress && (ethValue = web3.utils.toBN(ethValue).add(web3.utils.toBN(secondTokenAmount)).toString());

var request = {
    setupIndex,
    amount: mainTokenIndex === 0 ? firstTokenAmount : secondTokenAmount,
    amountIsLiquidityPool: false,
    positionOwner: myAddress
}

await farmingPresto.methods.openPosition(
    prestoAddress,
    operations,
    farmingContract.options.address,
    request
).send({value : ethValue});

Last updated