Fully on chain execution, with rebalancing of strategies across multiple asset classes
Automated liquidity Direction occurs in 3 steps:
The automated script offchain submits the target percentage for each asset class.
The VoteExecutorMaster and StrategyHandler calculates the current TVL and uses these percentages to determine how much each strategy for every asset class should hold.
The VoteExecutorMaster withdraw and deposits to strategies to meet this percentage.
On each strategy, we use oracles to determine the value of each position held in each strategy and sum it up to grab current TVL of the specific asset class. This is done by calling βgetDeployedAmountβ
Then, we calculate the positive or negative 'delta' for each strategy.
VoteExecutorMaster
else if (commandIndex == 2) {
// Handle all withdrawals first and then add all deposit actions to an array to be executed afterwards
(uint256 directionId, uint256 percent) = abi.decode(
messages[j].commandData,
(uint256, uint256)
);
(address strategyPrimaryToken, IStrategyHandler.LiquidityDirection memory direction) = handler.getDirectionFullInfoById(directionId);
if (direction.chainId == currentChain) {
console.log("directionId", directionId);
if (percent > 0) {
assetIdToDepositPercentages[direction.assetId].push(
Deposit(directionId, percent)
);
}
if (percent == 0) {
console.log("full exit");
IAlluoStrategyV2(direction.strategyAddress).exitAll(
direction.exitData,
10000,
strategyPrimaryToken,
address(this),
false,
false
);
handler.removeFromActiveDirections(directionId);
} else {
uint newAmount = (percent *
amountsDeployed[direction.assetId]) / 10000;
console.log("new", newAmount);
console.log("old", direction.latestAmount);
if (newAmount < direction.latestAmount) {
uint exitPercent = 10000 -
(newAmount * 10000) /
direction.latestAmount;
IAlluoStrategyV2(direction.strategyAddress)
.exitAll(
direction.exitData,
exitPercent,
strategyPrimaryToken,
address(this),
false,
false
);
} else if (newAmount != direction.latestAmount) {
uint depositAmount = newAmount -
direction.latestAmount;
assetIdToDepositList[direction.assetId].push(
Deposit(directionId, depositAmount)
);
}
}
}
This calculation is done by doing:
Current TVL of asset class * Allocation % = Target value.
Step 3: Withdraw and deposit to each strategy
Withdrawals happen immediately and deposits are queued because there is a chance of reverting in some edge cases. This is executed through executeDeposits() immediately after the vote is executed.
For example, say that we need to deposit 100k in each of pools A,B and C.
These are added to an array of deposits that are executed by calling executeDeposits(). In pseudocode:
["Deposit 100k in pool A", "Deposit 100k in pool B", "Deposit 100k in pool C"]
Once each direction is actioned, they are removed from the array.