Contract working on BSC Test and fails on BSC Main

Hello All,

I’m trying to implement a flashswap with pancakeswap exchange:-
so i call the source pair’s swap function as follows:

byte[] bytesParam1 = abiEncode.GetABIParamsEncoded(new FlashSwapParamsInput() { trgPair = Opportunity.oppPair[0].pairAddr, tokenAsset = token1Asset.addr, tokenMoney = token1Money.addr, asset0First = asset1First, asset1First = asset0First });
TransactionReceipt flashSwap1Receipt = await Opportunity.oppPair[1].pair.swap(new object[] { amount0Out, amount1Out, FlashSwapContract, bytesParam1 });

The source pair has the following swap method:

function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
    require(amount0Out > 0 || amount1Out > 0, 'Pancake: INSUFFICIENT_OUTPUT_AMOUNT');
    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
    require(amount0Out < _reserve0 && amount1Out < _reserve1, 'Pancake: INSUFFICIENT_LIQUIDITY');

    uint balance0;
    uint balance1;
    { // scope for _token{0,1}, avoids stack too deep errors
    address _token0 = token0;
    address _token1 = token1;
    require(to != _token0 && to != _token1, 'Pancake: INVALID_TO');
    if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
    if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
    if (data.length > 0) IPancakeCallee(to).pancakeCall(msg.sender, amount0Out, amount1Out, data);
    balance0 = IERC20(_token0).balanceOf(address(this));
    balance1 = IERC20(_token1).balanceOf(address(this));
    }
    uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
    uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
    require(amount0In > 0 || amount1In > 0, 'Pancake: INSUFFICIENT_INPUT_AMOUNT');
    { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
    uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(2));
    uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(2));
    require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'Pancake: K');
    }

the IPancakeCallee is my contract as follows:

function pancakeCall(address sender, uint amount0, uint amount1, bytes calldata data) external override {
    uint _amountBorrowed = amount0 > 0 ? amount0 : amount1;
    require(_amountBorrowed > 0, 'Borrowed amount must be > 0');
    
    // decode data(passed parameters)
    (
        address _trgPair,
        address _tokenAsset,
        address _tokenMoney ,
        bool asset0First,
        bool asset1First
    ) = abi.decode(data, (address, address, address, bool, bool));
    
    // Check Feasibility
    (uint _amountReceived, uint _amountRequired) = checkFeasibility(_amountBorrowed, msg.sender, _trgPair, asset0First, asset1First);
    require(_amountReceived > _amountRequired, 'No Anticipated Profit'); // no potential profit
    
    // Original balance of Money token
    uint _orgBalance = IERC20(_tokenMoney).balanceOf(address(this));
    
    // trade the asset for money on the target _trgPair
    TransferHelper.safeTransferAsset(_tokenAsset, _trgPair, _amountBorrowed);
    if(asset1First)
        IGenericPair(_trgPair).swap(0,_amountReceived,address(this),new bytes(0));
    else
        IGenericPair(_trgPair).swap(_amountReceived,0,address(this),new bytes(0));
    
    
    // get the actual received balance
    uint _amountActReceived = IERC20(_tokenMoney).balanceOf(address(this)) - _orgBalance;
    require(_amountActReceived > _amountRequired, 'No actual Profit to Earn');
    
    // repay the equivalent to the borrowed amount
    TransferHelper.safeTransferMoney(_tokenMoney, msg.sender, _amountRequired);
}

I hve tested the contract on test net and it flly working, but since deployed on main net had been in touble, this is the last implementation and it fails at the safeTransferAsset << the pair swap should have safetransfered the borrowed amount to my contract, so my contract should be holding the asset token (no need for approvals,… etc, it should trade it on the target pair, repay the loan and hold the profit

I’m a newbie and all help are much apprecited

Hi motash, welcome to the forums!

Can you link me your TestNet and your Live contracts? If we see the error, we can figure out what is failing and why.

One of the reasons might be because of the _amountBorrowed if what you are saying is true. Your other two variables in safeTransferAsset are probably valid.

But it is impossible to tell without seeing your contracts.

1 Like

Any update about this?