{"id":18704990,"url":"https://github.com/aave/upgradeable-configurable-rights-pool","last_synced_at":"2025-07-24T01:06:40.046Z","repository":{"id":54613438,"uuid":"312047910","full_name":"aave/upgradeable-configurable-rights-pool","owner":"aave","description":null,"archived":false,"fork":false,"pushed_at":"2021-02-08T14:34:33.000Z","size":509,"stargazers_count":10,"open_issues_count":0,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-19T15:19:11.967Z","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-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aave.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}},"created_at":"2020-11-11T17:54:35.000Z","updated_at":"2025-04-14T17:52:17.000Z","dependencies_parsed_at":"2022-08-13T21:40:15.194Z","dependency_job_id":null,"html_url":"https://github.com/aave/upgradeable-configurable-rights-pool","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aave/upgradeable-configurable-rights-pool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aave%2Fupgradeable-configurable-rights-pool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aave%2Fupgradeable-configurable-rights-pool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aave%2Fupgradeable-configurable-rights-pool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aave%2Fupgradeable-configurable-rights-pool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aave","download_url":"https://codeload.github.com/aave/upgradeable-configurable-rights-pool/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aave%2Fupgradeable-configurable-rights-pool/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266775383,"owners_count":23982273,"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-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":"2024-11-07T12:09:21.588Z","updated_at":"2025-07-24T01:06:40.015Z","avatar_url":"https://github.com/aave.png","language":"Solidity","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Configurable Rights Pool\n\nThis is a smart pool factory that allows anyone to deploy smart pools with (in the reference implementation) six \ndifferent rights that can be individually chosen:\n\n1) canPauseSwapping: pool creator can pause swaps (base pools can turn swapping on, but not off)\n2) canChangeSwapFee: pool creator can change trading fees (subject to min/max values)\n3) canChangeWeights: pool creator can change weights, either individually, or following a plan for gradual updates\n4) canAddRemoveTokens: pool creator can add/remove tokens (subject to the base pool limits)\n5) canWhitelistLPs: pool creator can specify a list of addresses allowed to add/remove liquidity\n6) canChangeCap: pool creator can change the BSP cap (max # of pool tokens)\n\n### CRPFactory.sol\n\nCreates new ConfigurableRightsPools \u0026 stores their addresses in a registry.\n\n#### `newCrp`\n\nCreates new Proxy for ConfigurableRightsPools with the caller as the contract controller.\n\n##### Params\n* `address factoryAddress` - BFactory address.\n* `PoolParams poolParams` - Structure holding the main parameters that define this pool\n* `RightsManager.Rights rights` - Structure defined in an external linked library, with boolean flags for each right\n* `smartPoolImplementation` - Address of the implementation contract for the CRP\n* `proxyAdmin` - Address to be assigned as admin of the proxy contract that uses the CRP implementation \n\n##### Pool Params structure\n* `string poolTokenSymbol` - Symbol of the Balancer Pool Token representing this pool\n* `string poolTokenName` - Name of the Balancer Pool Token representing this pool\n* `address[] constituentTokens` - Array of 2-8 token addresses. The pool will hold these.\n* `uint256[] tokenBalances` - Array of initial balances for the tokens specified above.\n* `uint256[] tokenWeights` - Array of initial weights for the tokens specified above.\n* `uint swapFee` - Initial swap fee for the pool (subject to min/max limits)\n\n##### Example Code\n\nNote that the weights are \"denormalized\" values, from 1 to 50 (really 49, as there must be at least two tokens, and the sum must be \u003c= 50\u003e). \u003cbr\u003eAs a rule of thumb, the denormalized weight of a token is half of its proportional weight (as a percentage). \u003cbr\u003e\u003cbr\u003eSo, a 98% / 2% pool's tokens would have denormalized weights of 49 and 1. With two tokens (A and B), the percentage value of A is denormA/(denormA + denormB). With 49/1, that's 49/(49+1) = 0.98, subject to the constraint: denormA + denormB \u003c= 50.\n\n```javascript\nconst permissions = {\n    canPauseSwapping: true,\n    canChangeSwapFee: true,\n    canChangeWeights: true,\n    canAddRemoveTokens: false,\n    canWhitelistLPs: false,\n    canChangeCap: false,\n};\n\nconst poolParams = {\n    poolTokenSymbol: 'BPT',\n    poolTokenName: 'BTP Example Name',\n    constituentTokens: [XYZ, WETH, DAI], // contract addresses\n    tokenBalances: [toWei('80000'), toWei('40'), toWei('10000')],\n    tokenWeights: [toWei('12'), toWei('1.5'), toWei('1.5')],\n    swapFee: toWei('0.003'), // 0.3%\n};\n\nawait crpFactory.newCrp(\n    bfactory.address,\n    poolParams,\n    permissions\n);\n```\n\u003chr\u003e\n\u003cstrong\u003eNote the following considerations when creating a new Configurable Rights Smart Pool\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003eYou must apply to list your token on the Balancer Exchange (or it will be shown as a bare address, with a warning)\u003c/li\u003e\n\u003cli\u003eIf your pool will be eligible for BAL rewards, you must apply to \"redirect\" the rewards to an account that can receive funds. (Without a redirect, the reward scripts would send the tokens to the CRP contract directly, where they cannot be recovered.)\u003c/li\u003e\n\u003cli\u003eOn a related note, unlike with core Balancer Pools, you cannot send tokens directly to the smart pool contract - they will be unrecoverable!\u003c/li\u003e\n\u003c/ul\u003e\n\nSee the [docs](https://docs.balancer.finance/protocol/bal-liquidity-mining/exchange-and-reward-listing) for more details on listing and redirects!\n\nThere is also a CRP creation [tutorial](https://docs.balancer.finance/guides/crp-tutorial). And the source code has a rich set of unit and scenario-based tests that demonstrate how to use all the features.\n\u003chr\u003e\n\n### ConfigurableRightsPool.sol\n\n\u003e **Pause Swapping Right**\n\n`setPublicSwap(bool publicSwap)`\n\nTurn swapping on (if publicSwap is true), or off - if the pool has that right assigned.\n\n\u003e **Change Swap Fee Right**\n\n`setSwapFee(uint swapFee)`\n\nSet the pool's swap fee (within min/max limits set by the underlying pool)\n\n\u003e **Change weights Right**\n\n`updateWeight(address token, uint newWeight)`\n\nUpdates weight for a given token, while keeping prices the same.\n\u003cbr\u003eThis will change the token balances, and cause tokens to be transferred to or from the caller's wallet\n\u003cbr\u003eNB: This cannot be done while a gradual update is underway (see below)\n\n`updateWeightsGradually(uint[] newWeights, uint startBlock, uint endBlock)`\n\nTransform all weights gradually and linearly from their present values to those specified in newWeights.\n\u003cbr\u003eThe weights are actually changed, between the specified start and end blocks, by pokeWeights.\n\u003cbr\u003eThis is very flexible. For instance, to halt the update sequence, call this function again with current weights.\n\n`pokeWeights()`\n\nCan be called by anyone (e.g., every block), to move the weights along the scheduled trajectory.\n\n\u003e **Add/Remove tokens Right**\n\n`commitAddToken(address token, uint balance, uint denormalizedWeight)`\n\nPrecommits a new token that can be applied addTokenTimeLockInBlocks blocks in the future.\n\n`applyAddToken()`\n\nApplies the token committed in the step above, and mints pool shares -\n\u003cbr\u003e(if at least addTokenTimeLockInBlocks blocks have passed since the commit).\n\n`removeToken(address token)`\n\nRemoves an existing token and returns the balance to the controller. You cannot remove a token while a gradual update is in progress. Note that removing all tokens effectively destroys the pool; i.e., you cannot add tokens back in. A one-token pool, while unusable (you can't swap with only one token), can still be restored to functionality by adding another token.\n\n\u003e **Whitelist Liquidity Provider Right**\n\n`whitelistLiquidityProvider(address provider)`\n\nAdd an address, after which this address can join a pool. (Initially, no one can add liquidity through joinPool, including the controller. The controller adds initial liquidity through createPool.)\n\n`removeWhitelistedLiquidityProvider(address provider)`\n\nRemove an address, after which this address can no longer join a pool. (Has no effect on existing LPs.)\n\n\u003e Creating a pool from the Factory\n\n`createPool(uint initialSupply)`\n\nCreates a pool with the given initial supply of Pool Tokens (with the asset allocation and weights specified by the factory)\n\u003cbr\u003eUse this constructor if you canChangeWeights is false, or you accept the default block time parameters for gradual weight change\n\n`createPool(uint initialSupply, uint minimumWeightChangeBlockPeriod, uint addTokenTimeLockInBlocks)`\n\nThis overload allows you to specify the block timing parameters (within limits), at pool creation time. They are fixed thereafter.\n\u003cbr\u003eSo you cannot call updateWeightsGradually with a duration \u003cem\u003e(endBlock - startBlock) \u003c minimumWeightChangeBlockPeriod\u003c/em\u003e.\n\u003cbr\u003e\u003cem\u003eaddTokenTimeLockInBlocks\u003c/em\u003e is the total number of blocks that have to pass before a new commited token can be applied\n\n\u003e Adding/Removing Liquidity\n\n`joinPool(uint poolAmountOut, uint[] maxAmountsIn)`\n\nDeposit at most the token amounts specified in \u003cem\u003emaxAmountsIn\u003c/em\u003e, and receive \u003cem\u003epoolAmountOut\u003c/em\u003e pool tokens in return.\n\n`exitPool(uint poolAmountIn, uint[] minAmountsOut)`\n\nRedeem \u003cem\u003epoolAmountIn\u003c/em\u003e pool tokens for at least the token amounts specified in \u003cem\u003eminAmountsOut\u003c/em\u003e\n\nThere are additional variations for specifying exact amounts (Uniswap-style)\n\n### PCToken.sol\n\nBalancer Smart Pool token. A standard ERC-20 with some extra math functions. Note that the math is normalized such that \"1\" is 10^18. These tokens have 18 decimals, and a configurable token symbol. (The token name is composed at run time from\na fixed prefix and the symbol.)\n\n### IBFactory.sol\n\nInterface for the [Balancer Factory](https://github.com/balancer-labs/balancer-core/blob/master/contracts/BFactory.sol).\n\n## NOTE\n\nYou cannot exit 100% using Pool Tokens (rebind will revert). It is possible to do using unbind with special permissions, but the trade-off is a potential loss of security. As described above, you can exit 1/3 at a time, or call removeToken if you have the right (keeping in mind that removing all tokens destroys the pool).\n\n## Getting Started - Local Testing\n\n`yarn`\n\n`yarn testrpc`\n\n`yarn test`\n\n## Contracts Deployment\nInstall dependencies\n\n`yarn`\n\nCompile contracts\n\n`yarn compile`\n\n### Configuration\nCreate an `.env` file from the `.env.example` and fill the variables\n\nThe default configuration for the pool rights available [here](./helpers/permissions.js) is the following:\n```\nconst permissions = {\n  canPauseSwapping: true,\n  canChangeSwapFee: true,\n  canChangeWeights: true,\n  canAddRemoveTokens: true,\n  canWhitelistLPs: false,\n  canChangeCap: false,\n}\n```\n\nNotes:\n- If `canWhitelistLPs` is `true` then the pool will be private and only whitelisted addresses can provide liquidity.\n- If `canChangeCap` is `true` then the default cap will be the initial supply (`100`), and it should be manually updated by calling `setCap` to allow new liquidity to be provided.\n\n### Run deployment scripts\nRunning the deployment script will:\n- Deploy the ConfigurableRightsPool implementation contract\n- Deploy the CRPFactory\n- Call `CRPFactory.newCrp` to create and initialize a new proxy smart pool using the ConfigurableRightsPool implementation address.\n- Give allowance to the crpPool on both involved tokens\n- Call `crpPool.createPool` on the proxy smart pool to create the BPool with the initial supply of 100 tokens\n\n#### Kovan deploy\n\n`yarn run deploy:kovan`\n\n#### Mainnet deploy\n\n`yarn run deploy:mainnet`\n\n## Verify contracts\n\nThe flattened versions of the contracts included in `flats` can be used to manually verify the contracts in the explorer with a single file.\nNotice that for the ConfigurableRightsPool implementation contract the libraries addresses should be included in the verification.\n\nTo generate them again, run `yarn run flatten`\n\nThen remove the duplicated lines of `SPDX-License-Identifier: GPL-3.0-or-later` and `pragma experimental ABIEncoderV2;` since that will produce and error in the explorer verification as it expect only one license and ABIEncoderV2 instruction per file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faave%2Fupgradeable-configurable-rights-pool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faave%2Fupgradeable-configurable-rights-pool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faave%2Fupgradeable-configurable-rights-pool/lists"}