{"id":29615488,"url":"https://github.com/cardinal-cryptography/common-aggregator","last_synced_at":"2025-09-25T11:46:44.560Z","repository":{"id":293244458,"uuid":"936155988","full_name":"Cardinal-Cryptography/common-aggregator","owner":"Cardinal-Cryptography","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-03T06:59:20.000Z","size":285,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-07-21T00:09:08.008Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Solidity","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Cardinal-Cryptography.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-02-20T16:07:40.000Z","updated_at":"2025-06-30T10:07:20.000Z","dependencies_parsed_at":"2025-05-14T11:51:38.741Z","dependency_job_id":"ead4c048-768b-427c-937f-fc801a9ff943","html_url":"https://github.com/Cardinal-Cryptography/common-aggregator","commit_stats":null,"previous_names":["cardinal-cryptography/common-aggregator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Cardinal-Cryptography/common-aggregator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cardinal-Cryptography%2Fcommon-aggregator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cardinal-Cryptography%2Fcommon-aggregator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cardinal-Cryptography%2Fcommon-aggregator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cardinal-Cryptography%2Fcommon-aggregator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Cardinal-Cryptography","download_url":"https://codeload.github.com/Cardinal-Cryptography/common-aggregator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Cardinal-Cryptography%2Fcommon-aggregator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276913317,"owners_count":25727124,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-25T02:00:09.612Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-07-21T00:03:41.489Z","updated_at":"2025-09-25T11:46:44.496Z","avatar_url":"https://github.com/Cardinal-Cryptography.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Common Aggregator\n\nYield aggregator for multiple ERC-4626 vaults, enabling a simple interaction via the ERC-4626 interface for users,\nwhile providing additional features like rebalancing and vault management to the *Management*.\n\nWhen depositing assets, users review the aggregator parameters set by *Management*, including\naggregated vaults and protocols corresponding to them, the maximum allocation limits for each of the aggregated vaults,\nand the performance fee, understanding and agreeing to the risks associated with them.\nThen, the *Rebalancer* chosen by *Management* can rebalance assets between protocols, according to their\nstrategy for optimizing between yield and risk.\n\n## Aggregation features\n\n### Funds distribution\n\nBy default, user deposits and withdrawals do not change proportions of the funds distributed between aggregated vaults.\n\nOne exception to this rule is a situation in which withdrawing the desired amount from one of the vaults is not possible at the moment.\nIn such a case, aggregator will withdraw disregarding the current proportions, prioritizing that the user is able to withdraw at all.\n\nAnother is that if one of the vaults imposes a limit on how much assets can `CommonAggregator` deposit to it \n(lower than the amount needed to maintain the proportions), then the deposit will succeed,\nbut the surplus will go to aggregator's own balance (until *Rebalancer* moves it to one of the vaults). \n\n### `ERC4626BufferedUpgradeable` - reward buffering\n\nWe implement an abstract contract `ERC4626BufferedUpgradeable` from which `CommonAggregator` inherits the reward buffering feature.\n\nReward buffering ensures that incoming `asset`s will be distributed to the depositors over some longer period of time, instead of instantly.\nIts goal is to prevent potential attack in which user deposits right before a reward distribution event,\neffectively capturing a portion of share holders' rewards for themselves.\n\n### State updates\n\nFor reward buffer to function properly it needs to be updated, so that newly gained `assets`s are accounted for,\nand later distributed to share holders. `ERC4626BufferedUpgradeable` specifies `updateHoldingsState` method, \nwhich can be called permissionlessly to update the buffer's state.\n\nIn `CommonAggregator`, such an update is run before each deposit and withdrawal action, so that the price-per-share\nused for minting/burning shares is computed based on the latest data.\nAdditionally, it is recommended to deploy an off-chain component that will run updates in case there is no user activity\nfor long periods of time.\n\n### Reward trading\n\n`CommonAggregator` makes it possible to distribute rewards which are paid out in tokens different than the `asset` token (eg. boosting airdrops).\nIt is achieved by allowing *Management* to designate a *reward trader* for such a token - an address to which given token can be freely transferred.\n\nThe intended usage of this feature is that *reward trader* should be a non-upgradable contract, which has a single method \ntrading the given token for `asset` (on some decentralized exchange) and tranferring it back to aggregator.\n\nIt is also possible for *reward trader* to be a trusted EOA in cases when CEX trading or other complex interactions are required. \n\n### Fees\n\nAggregator allows *Management* to set performance fee and its receiver.\nPerformance fee is taken as percantage of the gain (calculated and paid out during reward buffer's state update).\n\n## Security\nThe `CommonManagement` contract implements the role-management and extra security layer to the aggregator,\nLet's assume in this section the *Management* is a deployed instance of the `CommonManagement` contract.\nAny security-sensitive actions by it, like adding a new vault to the protocol, are timelocked. This allows users\nto react and withdraw their assets when they no longer agree with the strategy proposed by the *Management*.\n\nAdditionally, the *Management* can designate *Guardians* to monitor the protocol, and react by pausing it when unexpected\nevents occur, or cancel any incorrectly submitted timelocked actions. Importantly, even when the protocol is paused, users\ncan redeem their shares using the `emergencyRedeem` method, in exchange for shares of their underlying vaults.\n\n### Roles\n\n`CommonManagement` defines several roles, with different sets of privileges.\n\n*Owner* - owner of the `CommonManagement` contract. Has ability to assign and revoke all other roles\nand has all of their privileges. Can upgrade `CommonManagement` and `CommonAggregator` contracts (subject to a timelock).\n\n*Manager* - role performing management actions for `CommonAggregator`, less privilaged than *Owner*.\nHas ability to add/remove aggregated vaults and set *reward traders* (both subject to a timelock). \nHas all privileges of *Guardian* and *Rebalancer*.\n\n*Guardian* - role for quickly responding to incidents/mistakes. Can pause deposits/withdrawals and cancel timelocked actions.\n\n*Rebalancer* - can move funds between vaults to maximize gain or limit risk (subject to limits specified by the owner).\n\n## Development\n\n### Configuration\n\nIn order to pass arguments to `make` instructions that follow, copy contents of `.env.example` to `.env` and fill in the values.\n\n### Install dependencies\n\n```\nmake deps\n```\n\n### Compile solidity contracts\n\n```\nmake compile-contracts\n```\n\n### Running tests\n\n```\nmake test\n```\n\nTest coverage report is also available. For this `lcov` needs to be installed. This can be done on Debian/Ubuntu by running `sudo apt-get install lcov`.\n\nTo run coverage tests:\n```\nmake coverage-local\n```\nResults will be generated to `coverage/index.html` file.\n\n\n### Bulding and serving docs locally\n\n```\nmake doc-local\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcardinal-cryptography%2Fcommon-aggregator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcardinal-cryptography%2Fcommon-aggregator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcardinal-cryptography%2Fcommon-aggregator/lists"}