{"file_path":"src/contracts/GovernancePowerStrategy.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IGovernancePowerDelegationToken} from 'aave-token-v3/interfaces/IGovernancePowerDelegationToken.sol';\nimport {IBaseVotingStrategy} from '../interfaces/IBaseVotingStrategy.sol';\nimport {IGovernancePowerStrategy} from '../interfaces/IGovernancePowerStrategy.sol';\nimport {BaseVotingStrategy} from './BaseVotingStrategy.sol';\n\n/**\n * @title GovernancePowerStrategy\n * @author BGD Labs\n * @notice This contracts overrides the base voting strategy to return the power of specific assets used on the strategy.\n  * @dev These tokens will be used to get the proposition power to check if proposal can be created, and are the ones\n         needed on the voting machine chain voting strategy.\n */\ncontract GovernancePowerStrategy is\n  BaseVotingStrategy,\n  IGovernancePowerStrategy\n{\n  /// @inheritdoc IGovernancePowerStrategy\n  function getFullVotingPower(address user) external view returns (uint256) {\n    return\n      _getFullPowerByType(\n        user,\n        IGovernancePowerDelegationToken.GovernancePowerType.VOTING\n      );\n  }\n\n  /// @inheritdoc IGovernancePowerStrategy\n  function getFullPropositionPower(\n    address user\n  ) external view returns (uint256) {\n    return\n      _getFullPowerByType(\n        user,\n        IGovernancePowerDelegationToken.GovernancePowerType.PROPOSITION\n      );\n  }\n\n  /**\n   * @notice method to get the full user's power by type\n   * @param user address of the user to get the full power\n   * @param powerType type of the power to get (voting, proposal)\n   * @return full power of an user depending on the type (voting, proposal)\n   */\n  function _getFullPowerByType(\n    address user,\n    IGovernancePowerDelegationToken.GovernancePowerType powerType\n  ) internal view returns (uint256) {\n    uint256 fullGovernancePower;\n\n    address[] memory votingAssetList = getVotingAssetList();\n    for (uint256 i = 0; i < votingAssetList.length; i++) {\n      fullGovernancePower += IGovernancePowerDelegationToken(votingAssetList[i])\n        .getPowerCurrent(user, powerType);\n    }\n\n    return fullGovernancePower;\n  }\n}\n","deployed_bytecode":"0x608060405234801561001057600080fd5b50600436106100a95760003560e01c8063840261c511610071578063840261c514610141578063853bcd0314610161578063ac5af54b14610182578063bdf2878d1461018a578063c3533db2146101a4578063ee0c8554146101be57600080fd5b80630c5fc74b146100ae57806335f2a5c4146100d357806337dde417146100db57806348ccda3c146100fe57806369098bd71461012c575b600080fd5b6100b6604081565b6040516001600160801b0390911681526020015b60405180910390f35b6100b6600081565b6100ee6100e9366004610586565b6101d1565b60405190151581526020016100ca565b737fc66500c84a76ad7e9c93437bfc5ac33e2ddae95b6040516001600160a01b0390911681526020016100ca565b61013461024a565b6040516100ca91906105c9565b61015461014f366004610616565b610335565b6040516100ca9190610638565b61017461016f366004610616565b610489565b6040519081526020016100ca565b6100b6603481565b734da27a545c0c5b758a6ba100e3a049001de870f5610114565b73a700b4eb416be35b2911fd5dee80678ff64ff6c9610114565b6101746101cc366004610616565b610496565b6000806101dd84610335565b905060005b81515181101561023d57815180518290811061020057610200610691565b60200260200101516001600160801b0316846001600160801b03160361022b57600192505050610244565b80610235816106bd565b9150506101e2565b5060009150505b92915050565b6040805160038082526080820190925260609160009190602082018480368337019050509050737fc66500c84a76ad7e9c93437bfc5ac33e2ddae98160008151811061029857610298610691565b6001600160a01b0390921660209283029190910190910152734da27a545c0c5b758a6ba100e3a049001de870f5816001815181106102d8576102d8610691565b6001600160a01b039092166020928302919091019091015273a700b4eb416be35b2911fd5dee80678ff64ff6c98160028151811061031857610318610691565b6001600160a01b0390921660209283029190910190910152919050565b604080516020808201835260608083528351918201909352918252906001600160a01b038316737fc66500c84a76ad7e9c93437bfc5ac33e2ddae9148061039857506001600160a01b038316734da27a545c0c5b758a6ba100e3a049001de870f5145b156103f657604080516001808252818301909252906020808301908036833750505080825280516000919082906103d1576103d1610691565b60200260200101906001600160801b031690816001600160801b031681525050610244565b73a700b4eb416be35b2911fd5dee80678ff64ff6c8196001600160a01b0384160161024457604080516002808252606082018352909160208301908036833750505080825280516034919060009061045057610450610691565b60200260200101906001600160801b031690816001600160801b031681525050604081600001516001815181106103d1576103d1610691565b600061024482600161049f565b60006102448260005b60008060006104ac61024a565b905060005b8151811015610560578181815181106104cc576104cc610691565b60200260200101516001600160a01b031663b2f4201d87876040518363ffffffff1660e01b81526004016105019291906106d6565b602060405180830381865afa15801561051e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105429190610711565b61054c908461072a565b925080610558816106bd565b9150506104b1565b5090949350505050565b80356001600160a01b038116811461058157600080fd5b919050565b6000806040838503121561059957600080fd5b6105a28361056a565b915060208301356001600160801b03811681146105be57600080fd5b809150509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561060a5783516001600160a01b0316835292840192918401916001016105e5565b50909695505050505050565b60006020828403121561062857600080fd5b6106318261056a565b9392505050565b6020808252825182820182905280516040840181905260009291820190839060608601905b808310156106865783516001600160801b0316825292840192600192909201919084019061065d565b509695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016106cf576106cf6106a7565b5060010190565b6001600160a01b0383168152604081016002831061070457634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b60006020828403121561072357600080fd5b5051919050565b80820180821115610244576102446106a756fea2646970667358221220c9afc462add3c5529e753b8031db6a17197909fd15e2e28502f69b3ef71b86c864736f6c63430008130033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"paris","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":200},"remappings":[":aave-address-book/=lib/aave-address-book/src/",":aave-crosschain-infra-scripts/=lib/aave-crosschain-infra/scripts/",":aave-crosschain-infra/=lib/aave-crosschain-infra/src/",":aave-token-v2/=lib/aave-token-v3/lib/aave-token-v2/contracts/",":aave-token-v3/=lib/aave-token-v3/src/",":aave-v3-core/=lib/aave-address-book/lib/aave-v3-core/",":ds-test/=lib/forge-std/lib/ds-test/src/",":erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",":forge-std/=lib/forge-std/src/",":hyperlane-monorepo/=lib/aave-crosschain-infra/lib/hyperlane-monorepo/solidity/contracts/",":nitro-contracts/=lib/aave-crosschain-infra/lib/nitro-contracts/src/",":openzeppelin-contracts/=lib/openzeppelin-contracts/",":solidity-examples/=lib/aave-crosschain-infra/lib/solidity-examples/contracts/",":solidity-utils/=lib/solidity-utils/src/","lib/aave-address-book:@aave/core-v3/=lib/aave-address-book/lib/aave-v3-core/","lib/aave-address-book:@aave/periphery-v3/=lib/aave-address-book/lib/aave-v3-periphery/","lib/aave-address-book:aave-v3-core/=lib/aave-address-book/lib/aave-v3-core/","lib/aave-address-book:aave-v3-periphery/=lib/aave-address-book/lib/aave-v3-periphery/","lib/aave-address-book:ds-test/=lib/aave-address-book/lib/forge-std/lib/ds-test/src/","lib/aave-address-book:forge-std/=lib/aave-address-book/lib/forge-std/src/","lib/aave-crosschain-infra:@aave/core-v3/=lib/aave-crosschain-infra/lib/aave-address-book/lib/aave-v3-core/","lib/aave-crosschain-infra:@aave/periphery-v3/=lib/aave-crosschain-infra/lib/aave-address-book/lib/aave-v3-periphery/","lib/aave-crosschain-infra:@openzeppelin/=lib/aave-crosschain-infra/lib/openzeppelin-contracts/","lib/aave-crosschain-infra:aave-address-book/=lib/aave-crosschain-infra/lib/aave-address-book/src/","lib/aave-crosschain-infra:aave-v3-core/=lib/aave-crosschain-infra/lib/aave-address-book/lib/aave-v3-core/","lib/aave-crosschain-infra:aave-v3-periphery/=lib/aave-crosschain-infra/lib/aave-address-book/lib/aave-v3-periphery/","lib/aave-crosschain-infra:ds-test/=lib/aave-crosschain-infra/lib/forge-std/lib/ds-test/src/","lib/aave-crosschain-infra:forge-std/=lib/aave-crosschain-infra/lib/forge-std/src/","lib/aave-crosschain-infra:hyperlane-monorepo/=lib/aave-crosschain-infra/lib/hyperlane-monorepo/solidity/contracts/","lib/aave-crosschain-infra:nitro-contracts/=lib/aave-crosschain-infra/lib/nitro-contracts/src/","lib/aave-crosschain-infra:openzeppelin-contracts/=lib/aave-crosschain-infra/lib/openzeppelin-contracts/","lib/aave-crosschain-infra:solidity-examples/=lib/aave-crosschain-infra/lib/solidity-examples/contracts/","lib/aave-crosschain-infra:solidity-utils/=lib/aave-crosschain-infra/lib/solidity-utils/src/","lib/aave-token-v3:aave-token-v2/=lib/aave-token-v3/lib/aave-token-v2/contracts/","lib/aave-token-v3:ds-test/=lib/aave-token-v3/lib/forge-std/lib/ds-test/src/","lib/aave-token-v3:erc4626-tests/=lib/aave-token-v3/lib/openzeppelin-contracts/lib/erc4626-tests/","lib/aave-token-v3:forge-std/=lib/aave-token-v3/lib/forge-std/src/","lib/aave-token-v3:openzeppelin-contracts/=lib/aave-token-v3/lib/openzeppelin-contracts/","lib/aave-token-v3:openzeppelin/=lib/aave-token-v3/lib/openzeppelin-contracts/contracts/","lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/","lib/openzeppelin-contracts:ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/","lib/openzeppelin-contracts:erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/","lib/openzeppelin-contracts:forge-std/=lib/openzeppelin-contracts/lib/forge-std/src/","lib/openzeppelin-contracts:openzeppelin/=lib/openzeppelin-contracts/contracts/","lib/solidity-utils:ds-test/=lib/solidity-utils/lib/forge-std/lib/ds-test/src/","lib/solidity-utils:forge-std/=lib/solidity-utils/lib/forge-std/src/"]},"optimization_runs":200,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/partial_match/1/0xa198Fac58E02A5C5F8F7e877895d50cFa9ad1E04/","decoded_constructor_args":null,"compiler_version":"0.8.19+commit.7dd6d404","is_verified_via_verifier_alliance":null,"verified_at":"2024-03-08T17:06:02.233753Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60806040523480156200001157600080fd5b5060006200001e62000308565b8051604080518082019091526002815261313560f01b6020820152919250620000655760405162461bcd60e51b81526004016200005c919062000583565b60405180910390fd5b5060005b81518110156200030057600062000082826001620005e9565b90505b82518110156200012f57828181518110620000a457620000a4620005ff565b60200260200101516001600160a01b0316838381518110620000ca57620000ca620005ff565b60200260200101516001600160a01b031614156040518060400160405280600281526020016106e760f31b81525090620001195760405162461bcd60e51b81526004016200005c919062000583565b5080620001268162000615565b91505062000085565b5060006200015f8383815181106200014b576200014b620005ff565b60200260200101516200040a60201b60201c565b805151604080518082019091526002815261373960f01b60208201529192506200019e5760405162461bcd60e51b81526004016200005c919062000583565b5060005b81515181101562000286576000620001bc826001620005e9565b90505b82515181101562000270578251805182908110620001e157620001e1620005ff565b60200260200101516001600160801b0316836000015183815181106200020b576200020b620005ff565b60200260200101516001600160801b0316141560405180604001604052806002815260200161038360f41b815250906200025a5760405162461bcd60e51b81526004016200005c919062000583565b5080620002678162000615565b915050620001bf565b50806200027d8162000615565b915050620001a2565b508282815181106200029c576200029c620005ff565b60200260200101516001600160a01b03167fbe5e9292af59bc473a1eb54ed4b2a5bca33735ed12f2752005753b62027a02ca8260000151604051620002e2919062000631565b60405180910390a25080620002f78162000615565b91505062000069565b505062000680565b6040805160038082526080820190925260609160009190602082018480368337019050509050737fc66500c84a76ad7e9c93437bfc5ac33e2ddae981600081518110620003595762000359620005ff565b6001600160a01b03909216602092830291909101909101526200038d734da27a545c0c5b758a6ba100e3a049001de870f590565b81600181518110620003a357620003a3620005ff565b6001600160a01b0390921660209283029190910190910152620003d773a700b4eb416be35b2911fd5dee80678ff64ff6c990565b81600281518110620003ed57620003ed620005ff565b6001600160a01b0390921660209283029190910190910152919050565b60408051602081019091526060815260408051602081019091526060815262000444737fc66500c84a76ad7e9c93437bfc5ac33e2ddae990565b6001600160a01b0316836001600160a01b031614806200048057506001600160a01b038316734da27a545c0c5b758a6ba100e3a049001de870f5145b15620004e35760408051600180825281830190925290602080830190803683375050508082528051600091908290620004bd57620004bd620005ff565b60200260200101906001600160801b031690816001600160801b0316815250506200057d565b73a700b4eb416be35b2911fd5dee80678ff64ff6c8196001600160a01b038416016200057d576040805160028082526060820183529091602083019080368337505050808252805160349190600090620005415762000541620005ff565b60200260200101906001600160801b031690816001600160801b03168152505060408160000151600181518110620004bd57620004bd620005ff565b92915050565b600060208083528351808285015260005b81811015620005b25785810183015185820160400152820162000594565b506000604082860101526040601f19601f8301168501019250505092915050565b634e487b7160e01b600052601160045260246000fd5b808201808211156200057d576200057d620005d3565b634e487b7160e01b600052603260045260246000fd5b6000600182016200062a576200062a620005d3565b5060010190565b6020808252825182820181905260009190848201906040850190845b81811015620006745783516001600160801b0316835292840192918401916001016200064d565b50909695505050505050565b61077380620006906000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c8063840261c511610071578063840261c514610141578063853bcd0314610161578063ac5af54b14610182578063bdf2878d1461018a578063c3533db2146101a4578063ee0c8554146101be57600080fd5b80630c5fc74b146100ae57806335f2a5c4146100d357806337dde417146100db57806348ccda3c146100fe57806369098bd71461012c575b600080fd5b6100b6604081565b6040516001600160801b0390911681526020015b60405180910390f35b6100b6600081565b6100ee6100e9366004610586565b6101d1565b60405190151581526020016100ca565b737fc66500c84a76ad7e9c93437bfc5ac33e2ddae95b6040516001600160a01b0390911681526020016100ca565b61013461024a565b6040516100ca91906105c9565b61015461014f366004610616565b610335565b6040516100ca9190610638565b61017461016f366004610616565b610489565b6040519081526020016100ca565b6100b6603481565b734da27a545c0c5b758a6ba100e3a049001de870f5610114565b73a700b4eb416be35b2911fd5dee80678ff64ff6c9610114565b6101746101cc366004610616565b610496565b6000806101dd84610335565b905060005b81515181101561023d57815180518290811061020057610200610691565b60200260200101516001600160801b0316846001600160801b03160361022b57600192505050610244565b80610235816106bd565b9150506101e2565b5060009150505b92915050565b6040805160038082526080820190925260609160009190602082018480368337019050509050737fc66500c84a76ad7e9c93437bfc5ac33e2ddae98160008151811061029857610298610691565b6001600160a01b0390921660209283029190910190910152734da27a545c0c5b758a6ba100e3a049001de870f5816001815181106102d8576102d8610691565b6001600160a01b039092166020928302919091019091015273a700b4eb416be35b2911fd5dee80678ff64ff6c98160028151811061031857610318610691565b6001600160a01b0390921660209283029190910190910152919050565b604080516020808201835260608083528351918201909352918252906001600160a01b038316737fc66500c84a76ad7e9c93437bfc5ac33e2ddae9148061039857506001600160a01b038316734da27a545c0c5b758a6ba100e3a049001de870f5145b156103f657604080516001808252818301909252906020808301908036833750505080825280516000919082906103d1576103d1610691565b60200260200101906001600160801b031690816001600160801b031681525050610244565b73a700b4eb416be35b2911fd5dee80678ff64ff6c8196001600160a01b0384160161024457604080516002808252606082018352909160208301908036833750505080825280516034919060009061045057610450610691565b60200260200101906001600160801b031690816001600160801b031681525050604081600001516001815181106103d1576103d1610691565b600061024482600161049f565b60006102448260005b60008060006104ac61024a565b905060005b8151811015610560578181815181106104cc576104cc610691565b60200260200101516001600160a01b031663b2f4201d87876040518363ffffffff1660e01b81526004016105019291906106d6565b602060405180830381865afa15801561051e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105429190610711565b61054c908461072a565b925080610558816106bd565b9150506104b1565b5090949350505050565b80356001600160a01b038116811461058157600080fd5b919050565b6000806040838503121561059957600080fd5b6105a28361056a565b915060208301356001600160801b03811681146105be57600080fd5b809150509250929050565b6020808252825182820181905260009190848201906040850190845b8181101561060a5783516001600160a01b0316835292840192918401916001016105e5565b50909695505050505050565b60006020828403121561062857600080fd5b6106318261056a565b9392505050565b6020808252825182820182905280516040840181905260009291820190839060608601905b808310156106865783516001600160801b0316825292840192600192909201919084019061065d565b509695505050505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016106cf576106cf6106a7565b5060010190565b6001600160a01b0383168152604081016002831061070457634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b60006020828403121561072357600080fd5b5051919050565b80820180821115610244576102446106a756fea2646970667358221220c9afc462add3c5529e753b8031db6a17197909fd15e2e28502f69b3ef71b86c864736f6c63430008130033","name":"GovernancePowerStrategy","is_blueprint":false,"license_type":"none","is_fully_verified":false,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"paris","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":true,"additional_sources":[{"file_path":"lib/aave-token-v3/src/interfaces/IGovernancePowerDelegationToken.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\ninterface IGovernancePowerDelegationToken {\n  enum GovernancePowerType {\n    VOTING,\n    PROPOSITION\n  }\n\n  /**\n   * @dev emitted when a user delegates to another\n   * @param delegator the user which delegated governance power\n   * @param delegatee the delegatee\n   * @param delegationType the type of delegation (VOTING, PROPOSITION)\n   **/\n  event DelegateChanged(\n    address indexed delegator,\n    address indexed delegatee,\n    GovernancePowerType delegationType\n  );\n\n  // @dev we removed DelegatedPowerChanged event because to reconstruct the full state of the system,\n  // is enough to have Transfer and DelegateChanged TODO: document it\n\n  /**\n   * @dev delegates the specific power to a delegatee\n   * @param delegatee the user which delegated power will change\n   * @param delegationType the type of delegation (VOTING, PROPOSITION)\n   **/\n  function delegateByType(address delegatee, GovernancePowerType delegationType) external;\n\n  /**\n   * @dev delegates all the governance powers to a specific user\n   * @param delegatee the user to which the powers will be delegated\n   **/\n  function delegate(address delegatee) external;\n\n  /**\n   * @dev returns the delegatee of an user\n   * @param delegator the address of the delegator\n   * @param delegationType the type of delegation (VOTING, PROPOSITION)\n   * @return address of the specified delegatee\n   **/\n  function getDelegateeByType(address delegator, GovernancePowerType delegationType)\n    external\n    view\n    returns (address);\n\n  /**\n   * @dev returns delegates of an user\n   * @param delegator the address of the delegator\n   * @return a tuple of addresses the VOTING and PROPOSITION delegatee\n   **/\n  function getDelegates(address delegator)\n    external\n    view\n    returns (address, address);\n\n  /**\n   * @dev returns the current voting or proposition power of a user.\n   * @param user the user\n   * @param delegationType the type of delegation (VOTING, PROPOSITION)\n   * @return the current voting or proposition power of a user\n   **/\n  function getPowerCurrent(address user, GovernancePowerType delegationType)\n    external\n    view\n    returns (uint256);\n\n  /**\n   * @dev returns the current voting or proposition power of a user.\n   * @param user the user\n   * @return the current voting and proposition power of a user\n   **/\n  function getPowersCurrent(address user)\n    external\n    view\n    returns (uint256, uint256);\n\n  /**\n   * @dev implements the permit function as for https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md\n   * @param delegator the owner of the funds\n   * @param delegatee the user to who owner delegates his governance power\n   * @param delegationType the type of governance power delegation (VOTING, PROPOSITION)\n   * @param deadline the deadline timestamp, type(uint256).max for no deadline\n   * @param v signature param\n   * @param s signature param\n   * @param r signature param\n   */\n  function metaDelegateByType(\n    address delegator,\n    address delegatee,\n    GovernancePowerType delegationType,\n    uint256 deadline,\n    uint8 v,\n    bytes32 r,\n    bytes32 s\n  ) external;\n\n  /**\n   * @dev implements the permit function as for https://github.com/ethereum/EIPs/blob/8a34d644aacf0f9f8f00815307fd7dd5da07655f/EIPS/eip-2612.md\n   * @param delegator the owner of the funds\n   * @param delegatee the user to who delegator delegates his voting and proposition governance power\n   * @param deadline the deadline timestamp, type(uint256).max for no deadline\n   * @param v signature param\n   * @param s signature param\n   * @param r signature param\n   */\n  function metaDelegate(\n    address delegator,\n    address delegatee,\n    uint256 deadline,\n    uint8 v,\n    bytes32 r,\n    bytes32 s\n  ) external;\n}\n"},{"file_path":"src/contracts/BaseVotingStrategy.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IBaseVotingStrategy} from '../interfaces/IBaseVotingStrategy.sol';\nimport {Errors} from './libraries/Errors.sol';\n\n//import {AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';\n\n/**\n * @title BaseVotingStrategy\n * @author BGD Labs\n * @notice This contract contains the base logic of a voting strategy, being on governance chain or voting machine chain.\n */\nabstract contract BaseVotingStrategy is IBaseVotingStrategy {\n  function AAVE() public pure virtual returns (address) {\n    return 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9;\n  }\n\n  function STK_AAVE() public pure virtual returns (address) {\n    return 0x4da27a545c0c5B758a6BA100e3a049001de870f5;\n  }\n\n  function A_AAVE() public pure virtual returns (address) {\n    return 0xA700b4eB416Be35b2911fd5Dee80678ff64fF6C9;\n  }\n\n  uint128 public constant BASE_BALANCE_SLOT = 0;\n  uint128 public constant A_AAVE_BASE_BALANCE_SLOT = 52;\n  uint128 public constant A_AAVE_DELEGATED_STATE_SLOT = 64;\n\n  /// @dev on the constructor we get all the voting assets and emit the different asset configurations\n  constructor() {\n    address[] memory votingAssetList = getVotingAssetList();\n\n    // Check that voting strategy at least has one asset\n    require(votingAssetList.length != 0, Errors.NO_VOTING_ASSETS);\n\n    for (uint256 i = 0; i < votingAssetList.length; i++) {\n      for (uint256 j = i + 1; j < votingAssetList.length; j++) {\n        require(\n          votingAssetList[i] != votingAssetList[j],\n          Errors.REPEATED_STRATEGY_ASSET\n        );\n      }\n      VotingAssetConfig memory votingAssetConfig = getVotingAssetConfig(\n        votingAssetList[i]\n      );\n\n      require(\n        votingAssetConfig.storageSlots.length > 0,\n        Errors.EMPTY_ASSET_STORAGE_SLOTS\n      );\n\n      for (uint256 k = 0; k < votingAssetConfig.storageSlots.length; k++) {\n        for (\n          uint256 l = k + 1;\n          l < votingAssetConfig.storageSlots.length;\n          l++\n        ) {\n          require(\n            votingAssetConfig.storageSlots[k] !=\n              votingAssetConfig.storageSlots[l],\n            Errors.REPEATED_STRATEGY_ASSET_SLOT\n          );\n        }\n      }\n\n      emit VotingAssetAdd(votingAssetList[i], votingAssetConfig.storageSlots);\n    }\n  }\n\n  /// @inheritdoc IBaseVotingStrategy\n  function getVotingAssetList() public pure returns (address[] memory) {\n    address[] memory votingAssets = new address[](3);\n\n    votingAssets[0] = AAVE();\n    votingAssets[1] = STK_AAVE();\n    votingAssets[2] = A_AAVE();\n\n    return votingAssets;\n  }\n\n  /// @inheritdoc IBaseVotingStrategy\n  function getVotingAssetConfig(\n    address asset\n  ) public pure returns (VotingAssetConfig memory) {\n    VotingAssetConfig memory votingAssetConfig;\n\n    if (asset == AAVE() || asset == STK_AAVE()) {\n      votingAssetConfig.storageSlots = new uint128[](1);\n      votingAssetConfig.storageSlots[0] = BASE_BALANCE_SLOT;\n    } else if (asset == A_AAVE()) {\n      votingAssetConfig.storageSlots = new uint128[](2);\n      votingAssetConfig.storageSlots[0] = A_AAVE_BASE_BALANCE_SLOT;\n      votingAssetConfig.storageSlots[1] = A_AAVE_DELEGATED_STATE_SLOT;\n    } else {\n      return votingAssetConfig;\n    }\n\n    return votingAssetConfig;\n  }\n\n  /// @inheritdoc IBaseVotingStrategy\n  function isTokenSlotAccepted(\n    address token,\n    uint128 slot\n  ) external pure returns (bool) {\n    VotingAssetConfig memory votingAssetConfig = getVotingAssetConfig(token);\n    for (uint256 i = 0; i < votingAssetConfig.storageSlots.length; i++) {\n      if (slot == votingAssetConfig.storageSlots[i]) {\n        return true;\n      }\n    }\n    return false;\n  }\n}\n"},{"file_path":"src/contracts/libraries/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title Errors library\n * @author BGD Labs\n * @notice Defines the error messages emitted by the different contracts of the Aave Governance V3\n */\nlibrary Errors {\n  string public constant VOTING_PORTALS_COUNT_NOT_0 = '1'; // to be able to rescue voting portals count must be 0\n  string public constant AT_LEAST_ONE_PAYLOAD = '2'; // to create a proposal, it must have at least one payload\n  string public constant VOTING_PORTAL_NOT_APPROVED = '3'; // the voting portal used to vote on proposal must be approved\n  string public constant PROPOSITION_POWER_IS_TOO_LOW = '4'; // proposition power of proposal creator must be equal or higher than the specified threshold for the access level\n  string public constant PROPOSAL_NOT_IN_CREATED_STATE = '5'; // proposal should be in the CREATED state\n  string public constant PROPOSAL_NOT_IN_ACTIVE_STATE = '6'; // proposal must be in an ACTIVE state\n  string public constant PROPOSAL_NOT_IN_QUEUED_STATE = '7'; // proposal must be in a QUEUED state\n  string public constant VOTING_START_COOLDOWN_PERIOD_NOT_PASSED = '8'; // to activate a proposal vote, the cool down delay must pass\n  string public constant CALLER_NOT_A_VALID_VOTING_PORTAL = '9'; // only an allowed voting portal can queue a proposal\n  string public constant QUEUE_COOLDOWN_PERIOD_NOT_PASSED = '10'; // to execute a proposal a cooldown delay must pass\n  string public constant PROPOSAL_NOT_IN_THE_CORRECT_STATE = '11'; // proposal must be created but not executed yet to be able to be canceled\n  string public constant CALLER_NOT_GOVERNANCE = '12'; // caller must be governance\n  string public constant VOTER_ALREADY_VOTED_ON_PROPOSAL = '13'; // voter can only vote once per proposal using voting portal\n  string public constant WRONG_MESSAGE_ORIGIN = '14'; // received message must come from registered source address, chain id, CrossChainController\n  string public constant NO_VOTING_ASSETS = '15'; // Strategy must have voting assets\n  string public constant PROPOSAL_VOTE_ALREADY_CREATED = '16'; // vote on proposal can only be created once\n  string public constant INVALID_SIGNATURE = '17'; // submitted signature is not valid\n  string public constant PROPOSAL_VOTE_NOT_FINISHED = '18'; // proposal vote must be finished\n  string public constant PROPOSAL_VOTE_NOT_IN_ACTIVE_STATE = '19'; // proposal vote must be in active state\n  string public constant PROPOSAL_VOTE_ALREADY_EXISTS = '20'; // proposal vote already exists\n  string public constant VOTE_ONCE_FOR_ASSET = '21'; // an asset can only be used once per vote\n  string public constant USER_BALANCE_DOES_NOT_EXISTS = '22'; // to vote an user must have balance in the token the user is voting with\n  string public constant USER_VOTING_BALANCE_IS_ZERO = '23'; // to vote an user must have some balance between all the tokens selected for voting\n  string public constant MISSING_AAVE_ROOTS = '24'; // must have AAVE roots registered to use strategy\n  string public constant MISSING_STK_AAVE_ROOTS = '25'; // must have stkAAVE roots registered to use strategy\n  string public constant MISSING_STK_AAVE_SLASHING_EXCHANGE_RATE = '26'; // must have stkAAVE slashing exchange rate registered to use strategy\n  string public constant UNPROCESSED_STORAGE_ROOT = '27'; // root must be registered beforehand\n  string public constant NOT_ENOUGH_MSG_VALUE = '28'; // method was not called with enough value to execute the call\n  string public constant FAILED_ACTION_EXECUTION = '29'; // action failed to execute\n  string public constant SHOULD_BE_AT_LEAST_ONE_EXECUTOR = '30'; // at least one executor is needed\n  string public constant INVALID_EMPTY_TARGETS = '31'; // target of the payload execution must not be empty\n  string public constant EXECUTOR_WAS_NOT_SPECIFIED_FOR_REQUESTED_ACCESS_LEVEL =\n    '32'; // payload executor must be registered for the specified payload access level\n  string public constant PAYLOAD_NOT_IN_QUEUED_STATE = '33'; // payload must be en the queued state\n  string public constant TIMELOCK_NOT_FINISHED = '34'; // delay has not passed before execution can be called\n  string public constant PAYLOAD_NOT_IN_THE_CORRECT_STATE = '35'; // payload must be created but not executed yet to be able to be canceled\n  string public constant PAYLOAD_NOT_IN_CREATED_STATE = '36'; // payload must be in the created state\n  string public constant MISSING_A_AAVE_ROOTS = '37'; // must have aAAVE roots registered to use strategy\n  string public constant MISSING_PROPOSAL_BLOCK_HASH = '38'; // block hash for this proposal was not bridged before\n  string public constant PROPOSAL_VOTE_CONFIGURATION_ALREADY_BRIDGED = '39'; // configuration for this proposal bridged already\n  string public constant INVALID_VOTING_PORTAL_ADDRESS = '40'; // voting portal address can't be 0x0\n  string public constant INVALID_POWER_STRATEGY = '41'; // 0x0 is not valid as the power strategy\n  string public constant INVALID_EXECUTOR_ADDRESS = '42'; // executor address can't be 0x0\n  string public constant EXECUTOR_ALREADY_SET_IN_DIFFERENT_LEVEL = '43'; // executor address already being used as executor of a different level\n  string public constant INVALID_VOTING_DURATION = '44'; // voting duration can not be bigger than the time it takes to execute a proposal\n  string public constant VOTING_DURATION_NOT_PASSED = '45'; // at least votingDuration should have passed since voting started for a proposal to be queued\n  string public constant INVALID_PROPOSAL_ACCESS_LEVEL = '46'; // the bridged proposal access level does not correspond with the maximum access level required by the payload\n  string public constant PAYLOAD_NOT_CREATED_BEFORE_PROPOSAL = '47'; // payload must be created before proposal\n  string public constant INVALID_CROSS_CHAIN_CONTROLLER_ADDRESS = '48';\n  string public constant INVALID_MESSAGE_ORIGINATOR_ADDRESS = '49';\n  string public constant INVALID_ORIGIN_CHAIN_ID = '50';\n  string public constant INVALID_ACTION_TARGET = '51';\n  string public constant INVALID_ACTION_ACCESS_LEVEL = '52';\n  string public constant INVALID_EXECUTOR_ACCESS_LEVEL = '53';\n  string public constant INVALID_VOTING_PORTAL_CROSS_CHAIN_CONTROLLER = '54';\n  string public constant INVALID_VOTING_PORTAL_VOTING_MACHINE = '55';\n  string public constant INVALID_VOTING_PORTAL_GOVERNANCE = '56';\n  string public constant INVALID_VOTING_MACHINE_CHAIN_ID = '57';\n  string public constant G_INVALID_CROSS_CHAIN_CONTROLLER_ADDRESS = '58';\n  string public constant G_INVALID_IPFS_HASH = '59';\n  string public constant G_INVALID_PAYLOAD_ACCESS_LEVEL = '60';\n  string public constant G_INVALID_PAYLOADS_CONTROLLER = '61';\n  string public constant G_INVALID_PAYLOAD_CHAIN = '62';\n  string public constant POWER_STRATEGY_HAS_NO_TOKENS = '63'; // power strategy should at least have\n  string public constant INVALID_VOTING_CONFIG_ACCESS_LEVEL = '64';\n  string public constant VOTING_DURATION_TOO_SMALL = '65';\n  string public constant NO_BRIDGED_VOTING_ASSETS = '66';\n  string public constant INVALID_VOTER = '67';\n  string public constant INVALID_DATA_WAREHOUSE = '68';\n  string public constant INVALID_VOTING_MACHINE_CROSS_CHAIN_CONTROLLER = '69';\n  string public constant INVALID_L1_VOTING_PORTAL = '70';\n  string public constant INVALID_VOTING_PORTAL_CHAIN_ID = '71';\n  string public constant INVALID_VOTING_STRATEGY = '72';\n  string public constant INVALID_VOTE_CONFIGURATION_BLOCKHASH = '73';\n  string public constant INVALID_VOTE_CONFIGURATION_VOTING_DURATION = '74';\n  string public constant INVALID_GAS_LIMIT = '75';\n  string public constant INVALID_VOTING_CONFIGS = '76'; // a lvl2 voting configuration must be sent to initializer\n  string public constant INVALID_EXECUTOR_DELAY = '77';\n  string public constant REPEATED_STRATEGY_ASSET = '78';\n  string public constant EMPTY_ASSET_STORAGE_SLOTS = '79';\n  string public constant REPEATED_STRATEGY_ASSET_SLOT = '80';\n  string public constant INVALID_EXECUTION_TARGET = '81';\n  string public constant MISSING_VOTING_CONFIGURATIONS = '82'; // voting configurations for lvl1 and lvl2 must be included on initialization\n  string public constant INVALID_PROPOSITION_POWER = '83';\n  string public constant INVALID_YES_THRESHOLD = '84';\n  string public constant INVALID_YES_NO_DIFFERENTIAL = '85';\n  string public constant ETH_TRANSFER_FAILED = '86';\n  string public constant INVALID_INITIAL_VOTING_CONFIGS = '87'; // initial voting configurations can not be of the same level\n  string public constant INVALID_VOTING_PORTAL_ADDRESS_IN_VOTING_MACHINE = '88';\n  string public constant INVALID_VOTING_PORTAL_OWNER = '89';\n  string public constant CANCELLATION_FEE_REDEEM_FAILED = '90'; // cancellation fee was not able to be redeemed\n  string public constant INVALID_CANCELLATION_FEE_COLLECTOR = '91'; // collector can not be address 0\n  string public constant INVALID_CANCELLATION_FEE_SENT = '92'; // cancellation fee sent does not match the needed amount\n  string public constant CANCELLATION_FEE_ALREADY_REDEEMED = '93'; // cancellation fee already redeemed\n  string public constant INVALID_STATE_TO_REDEEM_CANCELLATION_FEE = '94'; // proposal state is not a valid state to redeem cancellation fee\n  string public constant MISSING_REPRESENTATION_ROOTS = '95'; // to represent a voter the representation roots need to be registered\n  string public constant CALLER_IS_NOT_VOTER_REPRESENTATIVE = '96'; // to represent a voter, caller must be the stored representative\n  string public constant VM_INVALID_GOVERNANCE_ADDRESS = '97'; // governance address can not be 0\n}\n"},{"file_path":"src/interfaces/IBaseVotingStrategy.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title IBaseVotingStrategy\n * @author BGD Labs\n * @notice interface containing the objects, events and method definitions of the BaseVotingStrategy contract\n */\ninterface IBaseVotingStrategy {\n  /**\n   * @notice object storing the information of the asset used for the voting strategy\n   * @param storageSlots list of slots for the balance of the specified token.\n            From that slot, by adding the address of the user, the correct balance can be taken.\n   */\n  struct VotingAssetConfig {\n    uint128[] storageSlots;\n  }\n\n  /**\n   * @notice emitted when an asset is added for the voting strategy\n   * @param asset address of the token to be added\n   * @param storageSlots array of storage positions of the balance mapping\n   */\n  event VotingAssetAdd(address indexed asset, uint128[] storageSlots);\n\n  /**\n   * @notice method to get the AAVE token address\n   * @return AAVE token contract address\n   */\n  function AAVE() external view returns (address);\n\n  /**\n   * @notice method to get the A_AAVE token address\n   * @return A_AAVE token contract address\n   */\n  function A_AAVE() external view returns (address);\n\n  /**\n   * @notice method to get the stkAAVE token address\n   * @return stkAAVE token contract address\n   */\n  function STK_AAVE() external view returns (address);\n\n  /**\n   * @notice method to get the slot of the balance of the AAVE and stkAAVE\n   * @return AAVE and stkAAVE base balance slot\n   */\n  function BASE_BALANCE_SLOT() external view returns (uint128);\n\n  /**\n   * @notice method to get the slot of the balance of the AAVE aToken\n   * @return AAVE aToken base balance slot\n   */\n  function A_AAVE_BASE_BALANCE_SLOT() external view returns (uint128);\n\n  /**\n   * @notice method to get the slot of the AAVE aToken delegation state\n   * @return AAVE aToken delegation state slot\n   */\n  function A_AAVE_DELEGATED_STATE_SLOT() external view returns (uint128);\n\n  /**\n   * @notice method to check if a token and slot combination is accepted\n   * @param token address of the token to check\n   * @param slot number of the token slot\n   * @return flag indicating if the token slot is accepted\n   */\n  function isTokenSlotAccepted(\n    address token,\n    uint128 slot\n  ) external view returns (bool);\n\n  /**\n   * @notice method to get the addresses of the assets that can be used for voting\n   * @return list of addresses of assets\n   */\n  function getVotingAssetList() external view returns (address[] memory);\n\n  /**\n   * @notice method to get the configuration for voting of an asset\n   * @param asset address of the asset to get the configuration from\n   * @return object with the asset configuration containing the list of storage slots\n   */\n  function getVotingAssetConfig(\n    address asset\n  ) external view returns (VotingAssetConfig memory);\n}\n"},{"file_path":"src/interfaces/IGovernancePowerStrategy.sol","source_code":"// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\n/**\n * @title IGovernancePowerStrategy\n * @author BGD Labs\n * @notice interface containing the methods definitions of the GovernancePowerStrategy contract\n */\ninterface IGovernancePowerStrategy {\n  /**\n * @notice method to get the full voting power of an user. This method is only use for consulting purposes.\n             As its not used for voting calculations, it is not needed to force blockNumber - 1 to protect against\n             FlashLoan attacks.\n   * @param user address where we want to get the power from\n   * @return full voting power of a user\n   */\n  function getFullVotingPower(address user) external view returns (uint256);\n\n  /**\n   * @notice method to get the full proposal power of an user. It is not needed to protect against FlashLoan\n             attacks because once user returns the tokens (power) the proposal will get canceled as proposal creator\n             will loose the proposition power.\n   * @param user address where we want to get the power from\n   * @return full proposition power of a user\n   */\n  function getFullPropositionPower(\n    address user\n  ) external view returns (uint256);\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint128[]","name":"storageSlots","type":"uint128[]"}],"name":"VotingAssetAdd","type":"event"},{"inputs":[],"name":"AAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"A_AAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"A_AAVE_BASE_BALANCE_SLOT","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"A_AAVE_DELEGATED_STATE_SLOT","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_BALANCE_SLOT","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STK_AAVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getFullPropositionPower","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getFullVotingPower","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getVotingAssetConfig","outputs":[{"components":[{"internalType":"uint128[]","name":"storageSlots","type":"uint128[]"}],"internalType":"struct IBaseVotingStrategy.VotingAssetConfig","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getVotingAssetList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"slot","type":"uint128"}],"name":"isTokenSlotAccepted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":null}