diff --git a/contracts/Governance/Aggregator/Aggregator.sol b/contracts/Governance/Aggregator/Aggregator.sol new file mode 100644 index 0000000..a5a8994 --- /dev/null +++ b/contracts/Governance/Aggregator/Aggregator.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.6.12; +pragma experimental ABIEncoderV2; + +import { GovernanceAggregator } from "./GovernanceAggregator.sol"; +import { RelayerAggregator } from "./RelayerAggregator.sol"; + +contract Aggregator is GovernanceAggregator, RelayerAggregator { + constructor( + address _ensRegistry, + address _relayerRegistry + ) public RelayerAggregator(_ensRegistry, _relayerRegistry) {} +} \ No newline at end of file diff --git a/contracts/Governance/Aggregator/GovernanceAggregator.sol b/contracts/Governance/Aggregator/GovernanceAggregator.sol new file mode 100644 index 0000000..c5d6ac9 --- /dev/null +++ b/contracts/Governance/Aggregator/GovernanceAggregator.sol @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.6.12; +pragma experimental ABIEncoderV2; + +import { Governance } from "../v1/Governance.sol"; + +contract GovernanceAggregator { + struct Proposal { + address proposer; + address target; + uint256 startTime; + uint256 endTime; + uint256 forVotes; + uint256 againstVotes; + bool executed; + bool extended; + Governance.ProposalState state; + } + + function getAllProposals(Governance governance) public view returns (Proposal[] memory proposals) { + proposals = new Proposal[](governance.proposalCount()); + + for (uint256 i = 0; i < proposals.length; i++) { + ( + address proposer, + address target, + uint256 startTime, + uint256 endTime, + uint256 forVotes, + uint256 againstVotes, + bool executed, + bool extended + ) = governance.proposals(i + 1); + + proposals[i] = Proposal({ + proposer: proposer, + target: target, + startTime: startTime, + endTime: endTime, + forVotes: forVotes, + againstVotes: againstVotes, + executed: executed, + extended: extended, + state: governance.state(i + 1) + }); + } + } + + function getGovernanceBalances(Governance governance, address[] calldata accs) public view returns (uint256[] memory amounts) { + amounts = new uint256[](accs.length); + for (uint256 i = 0; i < accs.length; i++) { + amounts[i] = governance.lockedBalance(accs[i]); + } + } + + function getUserData(Governance governance, address account) + public + view + returns ( + uint256 balance, + uint256 latestProposalId, + uint256 latestProposalIdState, + uint256 timelock, + address delegatee + ) + { + // Core core = Core(address(governance)); + balance = governance.lockedBalance(account); + latestProposalId = governance.latestProposalIds(account); + if (latestProposalId != 0) { + latestProposalIdState = uint256(governance.state(latestProposalId)); + } + timelock = governance.canWithdrawAfter(account); + delegatee = governance.delegatedTo(account); + } +} \ No newline at end of file diff --git a/contracts/Governance/Aggregator/RelayerAggregator.sol b/contracts/Governance/Aggregator/RelayerAggregator.sol new file mode 100644 index 0000000..df90b67 --- /dev/null +++ b/contracts/Governance/Aggregator/RelayerAggregator.sol @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.6.12; +pragma experimental ABIEncoderV2; + +interface ENSRegistry { + // Logged when the owner of a node assigns a new owner to a subnode. + event NewOwner(bytes32 indexed node, bytes32 indexed label, address owner); + + // Logged when the owner of a node transfers ownership to a new account. + event Transfer(bytes32 indexed node, address owner); + + // Logged when the resolver for a node changes. + event NewResolver(bytes32 indexed node, address resolver); + + // Logged when the TTL of a node changes + event NewTTL(bytes32 indexed node, uint64 ttl); + + // Logged when an operator is added or removed. + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); + + function setRecord( + bytes32 node, + address owner, + address resolver, + uint64 ttl + ) external; + + function setSubnodeRecord( + bytes32 node, + bytes32 label, + address owner, + address resolver, + uint64 ttl + ) external; + + function setSubnodeOwner( + bytes32 node, + bytes32 label, + address owner + ) external returns (bytes32); + + function setResolver(bytes32 node, address resolver) external; + + function setOwner(bytes32 node, address owner) external; + + function setTTL(bytes32 node, uint64 ttl) external; + + function setApprovalForAll(address operator, bool approved) external; + + function owner(bytes32 node) external view returns (address); + + function resolver(bytes32 node) external view returns (address); + + function ttl(bytes32 node) external view returns (uint64); + + function recordExists(bytes32 node) external view returns (bool); + + function isApprovedForAll(address owner, address operator) external view returns (bool); +} + +interface ENSResolver { + function addr(bytes32 node) external view returns (address); + + function text(bytes32 node, string calldata key) external view returns (string memory); +} + +interface RelayerRegistry { + function getRelayerBalance(address relayer) external view returns (uint256); + + function isRelayerRegistered(address relayer, address toResolve) external view returns (bool); +} + +struct Relayer { + address owner; + uint256 balance; + bool isRegistered; + string[20] records; +} + +contract RelayerAggregator { + ENSRegistry public immutable ensRegistry; + RelayerRegistry public immutable relayerRegistry; + + constructor(address _ensRegistry, address _relayerRegistry) public { + ensRegistry = ENSRegistry(_ensRegistry); + relayerRegistry = RelayerRegistry(_relayerRegistry); + } + + function relayersData(bytes32[] memory _relayers, string[] memory _subdomains) public view returns (Relayer[] memory) { + Relayer[] memory relayers = new Relayer[](_relayers.length); + + for (uint256 i = 0; i < _relayers.length; i++) { + relayers[i].owner = ensRegistry.owner(_relayers[i]); + ENSResolver resolver = ENSResolver(ensRegistry.resolver(_relayers[i])); + + for (uint256 j = 0; j < _subdomains.length; j++) { + bytes32 subdomainHash = keccak256(abi.encodePacked(_relayers[i], keccak256(abi.encodePacked(_subdomains[j])))); + relayers[i].records[j] = resolver.text(subdomainHash, "url"); + } + + relayers[i].isRegistered = relayerRegistry.isRelayerRegistered(relayers[i].owner, relayers[i].owner); + relayers[i].balance = relayerRegistry.getRelayerBalance(relayers[i].owner); + } + return relayers; + } +} \ No newline at end of file diff --git a/sepolia.json b/sepolia.json index 835103a..0942150 100644 --- a/sepolia.json +++ b/sepolia.json @@ -45,5 +45,6 @@ "TornadoStakingRewardsProxy": "0xCb64E517F916b88Bd8Fb1D8908D8fFD50a59CE31", "TornadoStakingRewardsImpl": "0x23d4993209746865F0D7A2de5E9579D9823c25D0", "TornadoRouter": "0xc150D7dc0d11b8357b3f4Add7c173558c5FCE90A", - "Echoer": "0x81D03CB94a761357629d89D4c921272F3fBfd80C" + "Echoer": "0x81D03CB94a761357629d89D4c921272F3fBfd80C", + "Aggregator": "0xb2B6032e8668C8603D095a4D3B55A660C9081317" } \ No newline at end of file