Alluo Explained
  • Welcome
    • 🧭 The Basics
  • Getting Started
    • πŸ’» The DeFi Web App
      • ❓ Connecting to the app
      • 🚜 Depositing into the farms
      • πŸ™Œ Other basics
      • 🏦 Importing your Mobile app wallet to Metamask
      • 🧬 Add the polygon network manually in Metamask.
      • ⛓️ Bridging Stablecoins from another chain
    • πŸ“±The Mobile app
      • πŸ—οΈ Setting up your account
      • 🏦 Depositing money into the app
      • πŸ™Œ Other basics
      • πŸ” Exporting your private key
    • πŸ“–Tech deep dive: Contract Address Library
  • Understanding Alluo
    • πŸ’΅ How does Alluo get the yield?
      • 🐰 Going deeper into the Alluo protocol rabbit hole
    • 🧐 FAQ
  • Tokens & Tokenomics
    • πŸͺ™ The tokens
    • πŸ‘¨β€πŸ”¬Tech deep dive: Interest Bearing {asset} token
      • Depositing
      • Withdrawals
      • IbAlluo on different chains
      • StIbAlluo and Superfluid
        • A closer look at the integration between IbAlluo and StIbAlluo
      • Using the IbAlluo contract directly to create streams
      • Liquidity Handler and adapters
        • Deposit process with the Liquidity Handler
        • Withdraw process with the Liquidity Handler
    • πŸ“ˆ Tokenomics
    • πŸ‘¨β€πŸ”¬Tech deep dive: Boosting yield by compounding rewards
      • Deposit into the Vault
      • Withdraw from the Vault
      • Redeem rewards
      • Automatic boosting with Alluo
      • FraxConvex Vaults
      • Managing withdrawal requests in IERC4626
  • Decentralisation and Trust
    • πŸ—³οΈ Trustless governance and execution
    • πŸ‘¨β€πŸ”¬Tech deep dive: Vote Executor Architecture
      • Off chain votes to on chain data
      • Onchain data verifcation
      • Automated execution of votes
        • Tokenomics
        • Liquidity Direction
        • Setting APYs on farms
      • Cross chain execution of votes
      • Manually submitting vote results onchain
    • ↔️Alluo Exchange
      • Interacting with the Exchange
    • vlAlluo Architecture
    • Contracts upgrades
    • Investment strategies
      • πŸ“ˆFrax Convex Finance
        • Adding new pools into the strategy
        • Investing into a pool
  • More Advanced Features
    • πŸ” Repeat payments, streaming IbAlluo
  • Product Updates
    • πŸ‘Œ Product Roadmap: Building the right products
    • πŸ’» Web App releases
    • πŸ“± Mobile App releases
    • 🏎️ Alluo Boost
  • tutorial projects
    • Example: USDC to streaming 1 IbAlluo per second
    • Example: Using IbAlluoUSD and Ricochet to do capital efficient DCA into ETH
Powered by GitBook
On this page
  • How to encode individual vote results:
  • How to get the final data to be submitted from individual encoded messages:
  1. Decentralisation and Trust
  2. Tech deep dive: Vote Executor Architecture

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.

PreviousCross chain execution of votesNextAlluo Exchange

Last updated 2 years ago

πŸ‘¨β€πŸ”¬