Manually submitting vote results onchain

To maintain decentralisation, we ensure that anyone on chain can submit data that reflects the vote results.

There are 2 main steps:

  1. Encode individual vote results and collate them

  2. Encode the sum of the the individual vote results

How to encode individual vote results:

The VoteExecutorMaster contract exposes view functions for this very purpose.

VoteExecutorMaster.sol
function encodeApyCommand(
    string memory _ibAlluoName, 
    uint256 _newAnnualInterest, 
    uint256 _newInterestPerSecond
) public pure  returns (uint256, bytes memory) {
    bytes memory encodedCommand = abi.encode(_ibAlluoName, _newAnnualInterest, _newInterestPerSecond);
    return (0, encodedCommand);
}

function encodeLiquidityCommand(
    string memory _codeName,
    address _strategyPrimaryToken,
    address _entryToken,
    uint256 _delta,
    bool _isDeposit
) public view  returns (uint256, bytes memory) {
    LiquidityDirection memory direction = liquidityDirection[_codeName];
    if(!_isDeposit){
        return (2, abi.encode(direction.strategyAddress, _delta, direction.chainId, _strategyPrimaryToken, _entryToken, direction.exitData));
    }
    else{
        return (3, abi.encode(direction.strategyAddress, _delta, direction.chainId, _strategyPrimaryToken, _entryToken, direction.entryData));
    }
}


function encodeMintCommand(
    uint256 _newMintAmount,
    uint256 _period
) public pure  returns (uint256, bytes memory) {
    bytes memory encodedCommand = abi.encode(_newMintAmount, _period);
    return (1, encodedCommand);
}

When encoding the command itself, two pieces of data are returned:

  1. An index

  2. The bytes encoded command data.

How to get the final data to be submitted from individual encoded messages:

VoteExecutorMaster.sol
function encodeAllMessages(uint256[] memory _commandIndexes, bytes[] memory _messages) public view  returns (bytes32 messagesHash, Message[] memory messages, bytes memory inputData) {
    uint256 timestamp = block.timestamp;
    require(_commandIndexes.length == _messages.length, "Array length mismatch");
    messages = new Message[](_commandIndexes.length);
    for (uint256 i; i < _commandIndexes.length; i++) {
        messages[i] = Message(_commandIndexes[i], _messages[i]);
    }
    messagesHash = keccak256(abi.encode(messages, timestamp));
    inputData = abi.encode(
            messagesHash,
            messages,
            timestamp
        );
}

Once you have all the indexes and command datas, collate them in arrays (ordered correctly in the pairs you received them from the view functions above) and then call encodeAllMessages.

You will then receive three pieces of data:

  1. Hash of the messages (messagesHash)

  2. Array of encoded messages (messages)

  3. Bytes encoded version of the array of encoded messages. (inputData)

You should then call submitData with (3) bytes encoded 'inputData'.

The hash of the messages should be posted in the discord channel and / or passed to the DAO multisig owners to be approved - to confirm that the submitted data does indeed reflect the results of the votes on snapshot.

Last updated