Cross chain execution of votes
Multiple VoteExecutor contracts on different chains
Last updated
Multiple VoteExecutor contracts on different chains
Last updated
IAnyCall(messagingInfo.anyCallAddress).anyCall(messagingInfo.nextChainExecutor, finalData, address(0), messagingInfo.nextChain, 0);/// @notice Receives SMPC call from Multichain and executes command after security checks
/// @dev Format of function name and return params are necessary (see docs: https://docs.multichain.org/developer-guide/anycall/anycall-v6/how-to-integrate-anycall-v6)
// Carry out two security checks:
// 1.) Confirm that the hash has been signed by the multisig
// 2.) Confirm that anyCall has been triggered by our VoteExecutorMaster contract
/// @param _data Data sent through by SMPC
/// @return success Required by Multichain
/// @return result Required by Multichain
function anyExecute(bytes memory _data) external returns (bool success, bytes memory result) {
(bytes memory message, bytes[] memory signs) = abi.decode(_data, (bytes, bytes[]));
(bytes32 hashed, Message[] memory _messages, uint256 timestamp) = abi.decode(message, (bytes32, Message[], uint256));
require(hashed == keccak256(abi.encode(_messages, timestamp)), "Hash doesn't match");
require(_checkSignedHashes(signs, hashed), "Hash has not been approved");
require(IAnyCallExecutor(messagingInfo.anyCallExecutor).context().from == voteExecutorMaster, "Origin of message invalid");
require(hashExecutionTime[hashed] ==0, "Duplicate hash" );
execute(_messages);
executionHistory.push(_data);
hashExecutionTime[hashed] = block.timestamp;
if (messagingInfo.nextChain != 0) {
IAnyCall(messagingInfo.anyCallAddress).anyCall(messagingInfo.nextChainExecutor, _data, address(0), messagingInfo.nextChain, 0);
}
success=true;
result="";
emit MessageReceived(hashed);
}
/// @notice Executes all messages received after authentication
/// @dev Loops through each command in the array and executes it.
/// @param _messages Array of messages
function execute(Message[] memory _messages) internal {
for (uint256 i; i < _messages.length; i++) {
Message memory currentMessage = _messages[i];
if (currentMessage.commandIndex == 0) {
(string memory ibAlluoSymbol, uint256 newAnnualInterest, uint256 newInterestPerSecond) = abi.decode(currentMessage.commandData, (string, uint256, uint256));
_changeAPY(newAnnualInterest, newInterestPerSecond, ibAlluoSymbol);
}
else if(currentMessage.commandIndex == 2) {
// Handle all withdrawals first and then add all deposit actions to an array to be executed afterwards
(address strategyAddress, uint256 delta, uint256 chainId, address strategyPrimaryToken, address exitToken, bytes memory data) = abi.decode(currentMessage.commandData, (address, uint256, uint256, address,address, bytes));
if (chainId == generalBridgingInfo.currentChain) {
IAlluoStrategy(strategyAddress).exitAll(data, delta, strategyPrimaryToken, address(this), false);
}
}
else if(currentMessage.commandIndex == 3) {
// Add all deposits to the queue.
(address strategyAddress, uint256 delta, uint256 chainId, address strategyPrimaryToken, address entryToken, bytes memory data) = abi.decode(currentMessage.commandData, (address, uint256, uint256, address,address, bytes));
if (chainId == generalBridgingInfo.currentChain) {
console.log("Deposit added", strategyAddress, delta);
tokenToDepositQueue[strategyPrimaryToken].depositList.push(Deposit(strategyAddress, delta, strategyPrimaryToken, entryToken, data));
}
}
}ataa
}