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