Multicall

Batch transaction with InitCore's multicall.

Multicall is a way to perform multiple interactions with a position (or multiple positions) while bypassing the health checks until the end of the multicall transaction. The function can only call methods in InitCore since the multicall uses delegatecall to itself.

The function creates a convenient way for users to perform multiple actions on their positions such as collateral or debt swaps, and debt rebalancing in a single transaction. One key use-case of the multicall is "flash borrow". The caller can borrow out the tokens first and eventually put collaterals back at the end of the multicall function.

Multicall also returns a bytes array of results.

Multicall accepts a list of bytes data as arguments. Each bytes data represents the encoded multicall data to be executed to InitCore.

// Example multicall function
function executeMulticall(uint256 posId, address lendingPoolA, uint256 borrowAAmount, address lendingPoolB, uint256 lendingBAmount) external returns (bytes[] memory results) {
    // 0. .. perform necessary actions for example pulling tokens from the caller ..
    
    // 1. build multicall bytes data
    //    Example: 1) borrow tokenA, 2) lend tokenB, 3) collateralize the deposited tokenB
    bytes[] memory calls = new bytes[](3);
    
    // build data for step 1) 
    calls[0] = abi.encodeWithSelector(IInitCore.borrow.selector, lendingPoolA, borrowAAmount, posId, address(this));
    
    // build data for step 2) – mint directly to position manager
    IERC20(ILendingPool(lendingPoolB).underlyingToken()).safeTransfer(lendingPoolB, lendingBAmount); // transfer underlying token to lending pool directly for mint
    calls[1] = abi.encodeWithSelector(IInitCore.mintTo.selector, lendingPoolB, POS_MANAGER);
    
    // build data for step 3)
    calls[2] = abi.encodeWithSelector(IInitCore.collateralize.selector, posId, lendingPoolB);
    
    results = IInitCore(INIT_CORE).multicall(calls);
}

Last updated