// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; pragma abicoder v2; interface IGovernanceStrategy { /** * @dev Returns the Proposition Power of a user at a specific block number. * @param user Address of the user. * @param blockNumber Blocknumber at which to fetch Proposition Power * @return Power number **/ function getPropositionPowerAt(address user, uint256 blockNumber) external view returns (uint256); /** * @dev Returns the total supply of Outstanding Proposition Tokens * @param blockNumber Blocknumber at which to evaluate * @return total supply at blockNumber **/ function getTotalPropositionSupplyAt(uint256 blockNumber) external view returns (uint256); /** * @dev Returns the total supply of Outstanding Voting Tokens * @param blockNumber Blocknumber at which to evaluate * @return total supply at blockNumber **/ function getTotalVotingSupplyAt(uint256 blockNumber) external view returns (uint256); /** * @dev Returns the Vote Power of a user at a specific block number. * @param user Address of the user. * @param blockNumber Blocknumber at which to fetch Vote Power * @return Vote number **/ function getVotingPowerAt(address user, uint256 blockNumber) external view returns (uint256); } interface IExecutorWithTimelock { /** * @dev emitted when a new pending admin is set * @param newPendingAdmin address of the new pending admin **/ event NewPendingAdmin(address newPendingAdmin); /** * @dev emitted when a new admin is set * @param newAdmin address of the new admin **/ event NewAdmin(address newAdmin); /** * @dev emitted when a new delay (between queueing and execution) is set * @param delay new delay **/ event NewDelay(uint256 delay); /** * @dev emitted when a new (trans)action is Queued. * @param actionHash hash of the action * @param target address of the targeted contract * @param value wei value of the transaction * @param signature function signature of the transaction * @param data function arguments of the transaction or callData if signature empty * @param executionTime time at which to execute the transaction * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target **/ event QueuedAction( bytes32 actionHash, address indexed target, uint256 value, string signature, bytes data, uint256 executionTime, bool withDelegatecall ); /** * @dev emitted when an action is Cancelled * @param actionHash hash of the action * @param target address of the targeted contract * @param value wei value of the transaction * @param signature function signature of the transaction * @param data function arguments of the transaction or callData if signature empty * @param executionTime time at which to execute the transaction * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target **/ event CancelledAction( bytes32 actionHash, address indexed target, uint256 value, string signature, bytes data, uint256 executionTime, bool withDelegatecall ); /** * @dev emitted when an action is Cancelled * @param actionHash hash of the action * @param target address of the targeted contract * @param value wei value of the transaction * @param signature function signature of the transaction * @param data function arguments of the transaction or callData if signature empty * @param executionTime time at which to execute the transaction * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target * @param resultData the actual callData used on the target **/ event ExecutedAction( bytes32 actionHash, address indexed target, uint256 value, string signature, bytes data, uint256 executionTime, bool withDelegatecall, bytes resultData ); /** * @dev Getter of the current admin address (should be governance) * @return The address of the current admin **/ function getAdmin() external view returns (address); /** * @dev Getter of the current pending admin address * @return The address of the pending admin **/ function getPendingAdmin() external view returns (address); /** * @dev Getter of the delay between queuing and execution * @return The delay in seconds **/ function getDelay() external view returns (uint256); /** * @dev Returns whether an action (via actionHash) is queued * @param actionHash hash of the action to be checked * keccak256(abi.encode(target, value, signature, data, executionTime, withDelegatecall)) * @return true if underlying action of actionHash is queued **/ function isActionQueued(bytes32 actionHash) external view returns (bool); /** * @dev Checks whether a proposal is over its grace period * @param governance Governance contract * @param proposalId Id of the proposal against which to test * @return true of proposal is over grace period **/ function isProposalOverGracePeriod( IAaveGovernanceV2 governance, uint256 proposalId ) external view returns (bool); /** * @dev Getter of grace period constant * @return grace period in seconds **/ function GRACE_PERIOD() external view returns (uint256); /** * @dev Getter of minimum delay constant * @return minimum delay in seconds **/ function MINIMUM_DELAY() external view returns (uint256); /** * @dev Getter of maximum delay constant * @return maximum delay in seconds **/ function MAXIMUM_DELAY() external view returns (uint256); /** * @dev Function, called by Governance, that queue a transaction, returns action hash * @param target smart contract target * @param value wei value of the transaction * @param signature function signature of the transaction * @param data function arguments of the transaction or callData if signature empty * @param executionTime time at which to execute the transaction * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target **/ function queueTransaction( address target, uint256 value, string memory signature, bytes memory data, uint256 executionTime, bool withDelegatecall ) external returns (bytes32); /** * @dev Function, called by Governance, that cancels a transaction, returns the callData executed * @param target smart contract target * @param value wei value of the transaction * @param signature function signature of the transaction * @param data function arguments of the transaction or callData if signature empty * @param executionTime time at which to execute the transaction * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target **/ function executeTransaction( address target, uint256 value, string memory signature, bytes memory data, uint256 executionTime, bool withDelegatecall ) external payable returns (bytes memory); /** * @dev Function, called by Governance, that cancels a transaction, returns action hash * @param target smart contract target * @param value wei value of the transaction * @param signature function signature of the transaction * @param data function arguments of the transaction or callData if signature empty * @param executionTime time at which to execute the transaction * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target **/ function cancelTransaction( address target, uint256 value, string memory signature, bytes memory data, uint256 executionTime, bool withDelegatecall ) external returns (bytes32); } interface IAaveGovernanceV2 { enum ProposalState { Pending, Canceled, Active, Failed, Succeeded, Queued, Expired, Executed } struct Vote { bool support; uint248 votingPower; } struct Proposal { uint256 id; address creator; IExecutorWithTimelock executor; address[] targets; uint256[] values; string[] signatures; bytes[] calldatas; bool[] withDelegatecalls; uint256 startBlock; uint256 endBlock; uint256 executionTime; uint256 forVotes; uint256 againstVotes; bool executed; bool canceled; address strategy; bytes32 ipfsHash; mapping(address => Vote) votes; } struct ProposalWithoutVotes { uint256 id; address creator; IExecutorWithTimelock executor; address[] targets; uint256[] values; string[] signatures; bytes[] calldatas; bool[] withDelegatecalls; uint256 startBlock; uint256 endBlock; uint256 executionTime; uint256 forVotes; uint256 againstVotes; bool executed; bool canceled; address strategy; bytes32 ipfsHash; } /** * @dev emitted when a new proposal is created * @param id Id of the proposal * @param creator address of the creator * @param executor The ExecutorWithTimelock contract that will execute the proposal * @param targets list of contracts called by proposal's associated transactions * @param values list of value in wei for each propoposal's associated transaction * @param signatures list of function signatures (can be empty) to be used when created the callData * @param calldatas list of calldatas: if associated signature empty, calldata ready, else calldata is arguments * @param withDelegatecalls boolean, true = transaction delegatecalls the taget, else calls the target * @param startBlock block number when vote starts * @param endBlock block number when vote ends * @param strategy address of the governanceStrategy contract * @param ipfsHash IPFS hash of the proposal **/ event ProposalCreated( uint256 id, address indexed creator, IExecutorWithTimelock indexed executor, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, bool[] withDelegatecalls, uint256 startBlock, uint256 endBlock, address strategy, bytes32 ipfsHash ); /** * @dev emitted when a proposal is canceled * @param id Id of the proposal **/ event ProposalCanceled(uint256 id); /** * @dev emitted when a proposal is queued * @param id Id of the proposal * @param executionTime time when proposal underlying transactions can be executed * @param initiatorQueueing address of the initiator of the queuing transaction **/ event ProposalQueued(uint256 id, uint256 executionTime, address indexed initiatorQueueing); /** * @dev emitted when a proposal is executed * @param id Id of the proposal * @param initiatorExecution address of the initiator of the execution transaction **/ event ProposalExecuted(uint256 id, address indexed initiatorExecution); /** * @dev emitted when a vote is registered * @param id Id of the proposal * @param voter address of the voter * @param support boolean, true = vote for, false = vote against * @param votingPower Power of the voter/vote **/ event VoteEmitted(uint256 id, address indexed voter, bool support, uint256 votingPower); event GovernanceStrategyChanged(address indexed newStrategy, address indexed initiatorChange); event VotingDelayChanged(uint256 newVotingDelay, address indexed initiatorChange); event ExecutorAuthorized(address executor); event ExecutorUnauthorized(address executor); /** * @dev Creates a Proposal (needs Proposition Power of creator > Threshold) * @param executor The ExecutorWithTimelock contract that will execute the proposal * @param targets list of contracts called by proposal's associated transactions * @param values list of value in wei for each propoposal's associated transaction * @param signatures list of function signatures (can be empty) to be used when created the callData * @param calldatas list of calldatas: if associated signature empty, calldata ready, else calldata is arguments * @param withDelegatecalls if true, transaction delegatecalls the taget, else calls the target * @param ipfsHash IPFS hash of the proposal **/ function create( IExecutorWithTimelock executor, address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas, bool[] memory withDelegatecalls, bytes32 ipfsHash ) external returns (uint256); /** * @dev Cancels a Proposal, * either at anytime by guardian * or when proposal is Pending/Active and threshold no longer reached * @param proposalId id of the proposal **/ function cancel(uint256 proposalId) external; /** * @dev Queue the proposal (If Proposal Succeeded) * @param proposalId id of the proposal to queue **/ function queue(uint256 proposalId) external; /** * @dev Execute the proposal (If Proposal Queued) * @param proposalId id of the proposal to execute **/ function execute(uint256 proposalId) external payable; /** * @dev Function allowing msg.sender to vote for/against a proposal * @param proposalId id of the proposal * @param support boolean, true = vote for, false = vote against **/ function submitVote(uint256 proposalId, bool support) external; /** * @dev Function to register the vote of user that has voted offchain via signature * @param proposalId id of the proposal * @param support boolean, true = vote for, false = vote against * @param v v part of the voter signature * @param r r part of the voter signature * @param s s part of the voter signature **/ function submitVoteBySignature( uint256 proposalId, bool support, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Set new GovernanceStrategy * Note: owner should be a timelocked executor, so needs to make a proposal * @param governanceStrategy new Address of the GovernanceStrategy contract **/ function setGovernanceStrategy(address governanceStrategy) external; /** * @dev Set new Voting Delay (delay before a newly created proposal can be voted on) * Note: owner should be a timelocked executor, so needs to make a proposal * @param votingDelay new voting delay in seconds **/ function setVotingDelay(uint256 votingDelay) external; /** * @dev Add new addresses to the list of authorized executors * @param executors list of new addresses to be authorized executors **/ function authorizeExecutors(address[] memory executors) external; /** * @dev Remove addresses to the list of authorized executors * @param executors list of addresses to be removed as authorized executors **/ function unauthorizeExecutors(address[] memory executors) external; /** * @dev Let the guardian abdicate from its priviledged rights **/ function __abdicate() external; /** * @dev Getter of the current GovernanceStrategy address * @return The address of the current GovernanceStrategy contracts **/ function getGovernanceStrategy() external view returns (address); /** * @dev Getter of the current Voting Delay (delay before a created proposal can be voted on) * Different from the voting duration * @return The voting delay in seconds **/ function getVotingDelay() external view returns (uint256); /** * @dev Returns whether an address is an authorized executor * @param executor address to evaluate as authorized executor * @return true if authorized **/ function isExecutorAuthorized(address executor) external view returns (bool); /** * @dev Getter the address of the guardian, that can mainly cancel proposals * @return The address of the guardian **/ function getGuardian() external view returns (address); /** * @dev Getter of the proposal count (the current number of proposals ever created) * @return the proposal count **/ function getProposalsCount() external view returns (uint256); /** * @dev Getter of a proposal by id * @param proposalId id of the proposal to get * @return the proposal as ProposalWithoutVotes memory object **/ function getProposalById(uint256 proposalId) external view returns (ProposalWithoutVotes memory); /** * @dev Getter of the Vote of a voter about a proposal * Note: Vote is a struct: ({bool support, uint248 votingPower}) * @param proposalId id of the proposal * @param voter address of the voter * @return The associated Vote memory object **/ function getVoteOnProposal(uint256 proposalId, address voter) external view returns (Vote memory); /** * @dev Get the current state of a proposal * @param proposalId id of the proposal * @return The current state if the proposal **/ function getProposalState(uint256 proposalId) external view returns (ProposalState); } library AaveGovernanceV2 { IAaveGovernanceV2 internal constant GOV = IAaveGovernanceV2(0xEC568fffba86c094cf06b22134B23074DFE2252c); IGovernanceStrategy public constant GOV_STRATEGY = IGovernanceStrategy(0xb7e383ef9B1E9189Fc0F71fb30af8aa14377429e); address public constant SHORT_EXECUTOR = 0xEE56e2B3D491590B5b31738cC34d5232F378a8D5; address public constant LONG_EXECUTOR = 0x79426A1c24B2978D90d7A5070a46C65B07bC4299; address public constant ARC_TIMELOCK = 0xAce1d11d836cb3F51Ef658FD4D353fFb3c301218; // https://github.com/aave/governance-crosschain-bridges address internal constant POLYGON_BRIDGE_EXECUTOR = 0xdc9A35B16DB4e126cFeDC41322b3a36454B1F772; address internal constant OPTIMISM_BRIDGE_EXECUTOR = 0x7d9103572bE58FfE99dc390E8246f02dcAe6f611; address internal constant ARBITRUM_BRIDGE_EXECUTOR = 0x7d9103572bE58FfE99dc390E8246f02dcAe6f611; address internal constant METIS_BRIDGE_EXECUTOR = 0x8EC77963068474a45016938Deb95E603Ca82a029; // https://github.com/bgd-labs/aave-v3-crosschain-listing-template/tree/master/src/contracts address internal constant CROSSCHAIN_FORWARDER_POLYGON = 0x158a6bC04F0828318821baE797f50B0A1299d45b; address internal constant CROSSCHAIN_FORWARDER_OPTIMISM = 0x5f5C02875a8e9B5A26fbd09040ABCfDeb2AA6711; address internal constant CROSSCHAIN_FORWARDER_ARBITRUM = 0xd1B3E25fD7C8AE7CADDC6F71b461b79CD4ddcFa3; address internal constant CROSSCHAIN_FORWARDER_METIS = 0x2fE52eF191F0BE1D98459BdaD2F1d3160336C08f; }