Multicall with Callback

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);
    }
}

Last updated