Multicall with callback are used together to perform actions on InitCore and external contracts. This combination of calls creates a liquidity hook to utilize liquidity on INIT to execute other logic outside of INIT.
One main usage of multicall with callback is to "one-click leverage" a position in a single transaction compared to having to perform multiple collateralize and borrow to attain the same amount of leverage.
// Example external contract that
// create INIT position from
// 1. borrow token from borrowing from INIT lending pool
// 2. collateral token from token out from swapping borrowed token
contract ExternalContract {
function coreCallback(address _sender, bytes calldata _data) external payable returns (bytes memory result) {
// check msg.sender is InitCore
require(msg.sender == INIT_CORE, 'sender not allowed');
// perform a swap on a DEX
// returns bytes result
}
// use callback to swap borrowed token and collateralize to an INIT position
function createInitPosition() external payable {
// 1. create position on INIT
uint256 posId = IInitCore(INIT_CORE).createPos(_mode, msg.sender);
// 2. transfer in token from user
IERC20(_tokenIn).safeTransferFrom(msg.sender, address(this), _amtIn);
bytes[] memory calls = new bytes[](4);
// 3. borrow from lending pool
calls[0] = abi.encodeWithSelector(IInitCore(INIT_CORE).borrow.selector, _borrowPool, _borrowAmt, posId, address(this));
// 4. callback to swap borrowed token
calls[1] = abi.encodeWithSelector(IInitCore(INIT_CORE).callback.selector, address(this), msg.value, abi.encode(_tokenIn, _borrowPool, _mintPool));
// 5. mint inToken from the result token of swap
calls[2] = abi.encodeWithSelector(IInitCore(INIT_CORE).mintTo.selector, _mintPool, POS_MANAGER);
// 6. collateralize inToken
calls[3] = abi.encodeWithSelector(IInitCore(INIT_CORE).collateralize.selector, posId, _mintPool);
// 7. make a multicall
IInitCore(INIT_CORE).multicall{value: msg.value}(calls);
}
}