/// @notice Execute strategy with price updates
/// @param creditAccount Target Credit Account
/// @param priceUpdates Array of (token, reserve, data) for on-demand oracles
/// @param strategyParams Your strategy-specific parameters
function executeWithPriceUpdates(
address creditAccount,
bytes[] calldata priceUpdates,
StrategyParams calldata strategyParams
) external {
uint256 numUpdates = priceUpdates.length;
// Build calls with price updates first
MultiCall[] memory calls = new MultiCall[](numUpdates + strategyParams.numCalls);
// Add all price updates at the beginning
for (uint256 i = 0; i < numUpdates; i++) {
(address token, bool reserve, bytes memory data) =
abi.decode(priceUpdates[i], (address, bool, bytes));
calls[i] = MultiCall({
target: address(creditFacade),
callData: abi.encodeCall(
ICreditFacadeV3Multicall.onDemandPriceUpdate,
(token, reserve, data)
)
});
}
// Add strategy calls after price updates
_buildStrategyCalls(calls, numUpdates, strategyParams);
creditFacade.multicall(creditAccount, calls);
}
contract PositionKeeper {
ICreditFacadeV3 public immutable creditFacade;
address public keeper;
mapping(address => bool) public managedAccounts;
modifier onlyKeeper() {
require(msg.sender == keeper, "Not keeper");
_;
}
/// @notice Rebalance position when health factor is low
function rebalance(
address creditAccount,
address tokenToSell,
uint256 sellAmount,
uint256 minRepay
) external onlyKeeper {
require(managedAccounts[creditAccount], "Not managed");
MultiCall[] memory calls = new MultiCall[](2);
// 1. Swap collateral for underlying
calls[0] = MultiCall({
target: uniswapAdapter,
callData: abi.encodeCall(
IUniswapV3Adapter.exactInputSingle,
(swapParams)
)
});
// 2. Repay debt using diff pattern
calls[1] = MultiCall({
target: address(creditFacade),
callData: abi.encodeCall(
ICreditFacadeV3Multicall.decreaseDebt,
(minRepay)
)
});
// Execute as bot (requires bot permissions on account)
creditFacade.botMulticall(creditAccount, calls);
}
}
// This will revert if msg.sender is not account owner
creditFacade.multicall(creditAccount, calls);
// For keeper/bot access, the owner must grant permissions first
// This is done via setBotPermissions in a multicall