From 980cae1a244c55c9459115bcd96bba9da4b4a957 Mon Sep 17 00:00:00 2001 From: Tom French Date: Fri, 18 Nov 2022 00:43:28 +0000 Subject: [PATCH] feat: begin adding tracking for state of permissions granted onchain --- pkg/permissions/CHANGELOG.md | 3 + pkg/permissions/README.md | 14 + .../labelled-accounts/mainnet.json | 13 + pkg/permissions/labelled-accounts/readme.md | 5 + pkg/permissions/package.json | 41 ++ pkg/permissions/permissions/actionIds.json | 129 ++++ pkg/permissions/permissions/functions.json | 612 ++++++++++++++++++ pkg/permissions/permissions/unrecognised.json | 23 + .../scripts/getCallableFunctions.ts | 65 ++ .../scripts/getPermissionedAccounts.ts | 21 + .../scripts/getUnrecognisedActionIds.ts | 28 + pkg/permissions/src/accounts.ts | 35 + pkg/permissions/src/actionIds.ts | 39 ++ pkg/permissions/src/labelling.ts | 5 + pkg/permissions/src/types.ts | 16 + pkg/permissions/tsconfig.json | 10 + yarn.lock | 17 + 17 files changed, 1076 insertions(+) create mode 100644 pkg/permissions/CHANGELOG.md create mode 100644 pkg/permissions/README.md create mode 100644 pkg/permissions/labelled-accounts/mainnet.json create mode 100644 pkg/permissions/labelled-accounts/readme.md create mode 100644 pkg/permissions/package.json create mode 100644 pkg/permissions/permissions/actionIds.json create mode 100644 pkg/permissions/permissions/functions.json create mode 100644 pkg/permissions/permissions/unrecognised.json create mode 100644 pkg/permissions/scripts/getCallableFunctions.ts create mode 100644 pkg/permissions/scripts/getPermissionedAccounts.ts create mode 100644 pkg/permissions/scripts/getUnrecognisedActionIds.ts create mode 100644 pkg/permissions/src/accounts.ts create mode 100644 pkg/permissions/src/actionIds.ts create mode 100644 pkg/permissions/src/labelling.ts create mode 100644 pkg/permissions/src/types.ts create mode 100644 pkg/permissions/tsconfig.json diff --git a/pkg/permissions/CHANGELOG.md b/pkg/permissions/CHANGELOG.md new file mode 100644 index 0000000000..1512c42162 --- /dev/null +++ b/pkg/permissions/CHANGELOG.md @@ -0,0 +1,3 @@ +# Changelog + +## Unreleased diff --git a/pkg/permissions/README.md b/pkg/permissions/README.md new file mode 100644 index 0000000000..536ad1df64 --- /dev/null +++ b/pkg/permissions/README.md @@ -0,0 +1,14 @@ +# Balancer + +# Balancer V2 Permissions + +[![NPM Package](https://img.shields.io/npm/v/@balancer-labs/v2-permissions.svg)](https://www.npmjs.org/package/@balancer-labs/v2-permissions) +[![GitHub Repository](https://img.shields.io/badge/github-deployments-lightgrey?logo=github)](https://github.com/balancer-labs/balancer-v2-monorepo/tree/master/pkg/permissions) + +## Overview + +### Installation + +```console +$ npm install @balancer-labs/v2-permissions +``` diff --git a/pkg/permissions/labelled-accounts/mainnet.json b/pkg/permissions/labelled-accounts/mainnet.json new file mode 100644 index 0000000000..47f1a5bb43 --- /dev/null +++ b/pkg/permissions/labelled-accounts/mainnet.json @@ -0,0 +1,13 @@ +{ + "0x10a19e7ee7d7f8a52822f6817de8ea18204f2e4f": "DAO_MULTISIG", + "0x166f54f44f271407f24aa1be415a730035637325": "BALLER_OPS_MULTISIG", + "0x75a52c0e32397a3fc0c052e2ceb3479802713cf4": "LINEAR_POOL_CONTROLLER_BALLER_MULTISIG", + "0xf4a80929163c5179ca042e1b292f5efbbe3d89e6": "SWAP_FEE_CONTROLLER_BALLER_MULTISIG", + "0xc38c5f97b34e175ffd35407fc91a937300e33860": "LM_MULTISIG", + "0x7c68c42de679ffb0f16216154c996c354cf1161b": "TREASURY_MULTISIG", + "0xa29f61256e948f3fb707b4b3b138c5ccb9ef9888": "EMERGENCY_SUBDAO_MULTISIG", + "0x02f35dA6A02017154367Bc4d47bb6c7D06C7533B": "BLABS_OPS_MULTISIG", + "0xd2eb7bd802a7ca68d9acd209bec4e664a9abdd7b": "BLABS_VEBAL_MULTISIG", + "0xe4a8ed6c1d8d048bd29a00946bfcf2db10e7923b": "GAUNTLET_FEE_SETTER", + "0xc92e8bdf79f0507f65a392b0ab4667716bfe0110": "GNOSIS_PROTOCOL_RELAYER" +} diff --git a/pkg/permissions/labelled-accounts/readme.md b/pkg/permissions/labelled-accounts/readme.md new file mode 100644 index 0000000000..daf27ac714 --- /dev/null +++ b/pkg/permissions/labelled-accounts/readme.md @@ -0,0 +1,5 @@ +# Labelled Accounts + +This directory contains accounts which hold permissions over areas of the the Balancer Protocol which aren't deployed as part of the Balancer Protocol itself (as these are tracked in the `@balancer-labs/v2-deployments` package). These are generally Safe multisigs or externally developed contracts. + +Balancer DAO maintains documentation on the list of Safe multisigs it uses on [Notion](https://quark-ceres-740.notion.site/Multisig-List-Guidelines-402e18cff13e4f2fa571bc14ed007546) diff --git a/pkg/permissions/package.json b/pkg/permissions/package.json new file mode 100644 index 0000000000..7f3e6e610c --- /dev/null +++ b/pkg/permissions/package.json @@ -0,0 +1,41 @@ +{ + "name": "@balancer-labs/v2-permissions", + "version": "0.1.0", + "description": "Registry of permissions granted on Balancer's Authorizer contract", + "license": "GPL-3.0-only", + "homepage": "https://github.com/balancer-labs/balancer-v2-monorepo/tree/master/pkg/permissions#readme", + "repository": { + "type": "git", + "url": "https://github.com/balancer-labs/balancer-v2-monorepo.git", + "directory": "pkg/permissions" + }, + "bugs": { + "url": "https://github.com/balancer-labs/balancer-v2-monorepo/issues" + }, + "main": "dist/index.js", + "module": "dist/index.esm.js", + "browser": "dist/index.umd.js", + "typings": "dist/index.d.ts", + "files": [ + "dist/" + ], + "scripts": { + "permissions:update": "yarn ts-node scripts/getPermissionedAccounts.ts", + "permissions:map": "yarn ts-node scripts/getCallableFunctions.ts", + "permissions:unknown": "yarn ts-node scripts/getUnrecognisedActionIds.ts", + "lint": "eslint . --ext .ts --ignore-path ../../.eslintignore --max-warnings 0", + "test": "hardhat test ./**/test/*.ts" + }, + "devDependencies": { + "@types/node": "^14.14.31", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "@typescript-eslint/parser": "^5.41.0", + "chalk": "^4.1.2", + "eslint": "^8.26.0", + "eslint-plugin-prettier": "^4.2.1", + "node-fetch": "^2.6.7", + "prettier": "^2.7.1", + "ts-node": "^10.9.1", + "typescript": "^4.0.2" + } +} diff --git a/pkg/permissions/permissions/actionIds.json b/pkg/permissions/permissions/actionIds.json new file mode 100644 index 0000000000..56532e75d6 --- /dev/null +++ b/pkg/permissions/permissions/actionIds.json @@ -0,0 +1,129 @@ +{ + "0x02f35da6a02017154367bc4d47bb6c7d06c7533b": [ + "0x5bcdcc8d471eea0c6345d3dd65ad4997a32054e1e0672b780a9b6c36df0166a3", + "0x8b2c6767a8c426408240798cd82acf7ba6091320da176d0b1ab39e99fd5c409d", + "0x3f63974a377ba4713661ede455bceda6686a0395f8b8ed8701ad1f13bb926c4d", + "0xc89b780137460c1010bc938658c3b615990dd348e27ff1d095be12e6fe617f64", + "0xbdac75576424959cffc7f91ec4674a05fd1c62bedcbcbce9dab046c58c881950" + ], + "DAO_MULTISIG": [ + "0xac0fcdc4520d7bde1c58bbefd7c8dd39aaf382a20c27991134c14fe63d2c96f3", + "0x43cd68bd7db0472f3fac100d3f402a603c8ab62e816feff20dbe3ec6c6e61b89", + "0xec1d467d9ab03a0079c22a89037209f5763aec973897ea763e2cf25d71a5f12e", + "0x4907aec017cb19a28528e722251b40fd7c5eadd4f4a0f0c6a9bca9888f8a0b7f", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x453b670b2708db1ba5df1da1d48add0564558624efac456e43e9c9fff99d51af", + "0xb28b769768735d011b267f781c3be90bce51d5059ba015bc7a28b3e882fb2083" + ], + "0x170027069fd114bff2f57b0fc796df93290c02a6": [ + "0x3c7de1d8a207c7901ec612f9f0f50957da016911a50d5c22bbe5c9f4f3392d95", + "0xb5593fe09464f360ecf835d5b9319ce69900ae1b29d13844b73c250b1f5f92fb" + ], + "0x239e55f427d44c3cc793f49bfb507ebe76638a2b": [ + "0xdddd30813da50fda5faba482fd2937d0c6165d2faf027d3dfbd1554f3d7d47ff" + ], + "0x2536dfeecb7a0397cf98edada8486254533b1afa": [ + "0x78ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653", + "0x7b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff", + "0x1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30", + "0x0014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8", + "0xeba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b498", + "0xc149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d34" + ], + "0x2ffb7b215ae7f088ec2530c7aa8e1b24e398f26a": [ + "0xf49d7ffb5922642adc9f29cfb52b2214e81e0b0e54e9cd1e9f70439f0011f368" + ], + "0x5ef4c5352882b10893b70dbcaa0c000965bd23c5": [ + "0xb2b6e48fa160a7c887d9d7a68b6a9bb9d47d4953d33e07f3a39e175d75e97796" + ], + "LINEAR_POOL_CONTROLLER_BALLER_MULTISIG": [ + "0xe4814396e9db5314024c424f43d6a129829efad6c545df373b226431cbcadbd3", + "0x2256d78edacd087428321791a930d4f9fd7acf56e8862187466f1caf179c1a08", + "0x1e3ce02b9d143fb44dc00c908d6b454553cf1c8c48e54090fa1f5fdd18a8e6b9" + ], + "TREASURY_MULTISIG": [ + "0x826ac7ce861f2a54e071e6c724653757fdd1259804eb1ca7f040aa1cd09923fe" + ], + "0x886a3ec7bcc508b8795990b60fa21f85f9db7948": [ + "0x7b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff", + "0x78ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653", + "0x1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30", + "0xeba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b498", + "0x0014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8", + "0xc149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d34" + ], + "0x97207b095e4d5c9a6e4cfbfcd2c3358e03b90c4a": [ + "0xb28b769768735d011b267f781c3be90bce51d5059ba015bc7a28b3e882fb2083", + "0xbe2a180d5cc5d803a8eec4cea569989fc1c593d7eeadd1f262f360a68b0e842e" + ], + "EMERGENCY_SUBDAO_MULTISIG": [ + "0x8d329099a8220fbd27ff3cf304a4cb1dae32335654ec5115c3a643ac0e623418", + "0xc0d91e75884e4ce70f827133990e1c6ee501b41ad3096d25bce3c04d2976c3e7", + "0xa738fa584fff6afe4e319db36f7f5270924047e5e2c04a1712cbfc082e3fd078", + "0x367e95c6cc9f3041f3c6ee21b06ef8992a82318a6b2adbbfb6af3ee601769a30", + "0x8186826062c35b40965262f49014e5ca45b7064fba48b12107613bce22571a99", + "0xfef90c64be79cb170a20e526196e7c8f2f37f441ae85c945c18a91a64777d309", + "0x84163b5cca492497c5fa264018819677910a8022689972cc54566d8667dbce68", + "0xa5a62b55fdf9496f8e1b3feba479423a4349b385bd444f893b3cd4cf9387ce3f", + "0x0d9dbee65c669ef9d726a603957e4a610b40b2662eba759efbedfe87216ec751" + ], + "0xac9f49ef3ab0bbc929f7b1bb0a17e1fca5786251": [ + "0xeba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b498", + "0x7b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff", + "0x1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30", + "0x78ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653", + "0xc149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d34", + "0x0014a06d322ff07fcc02b12f93eb77bb76e28cdee4fc0670b9dec98d24bbfec8" + ], + "LM_MULTISIG": [ + "0x5c62111a5fb2cd09521d2805fb5080f8db7f341691a1e38c34a5ededb8f8bfd3", + "0x590e300e371ba81baff1c912e578fdecbfa490f39994607a18ee692ab942f846", + "0x77238124388523487417c8ad8cec25726833e50ca5cab74a4924470fee49ae5d", + "0x72c4c054ad03b4f5f0ba716c30d74c6f27fafb105c850cb59e2b6fec32a42f2f", + "0x5dce9596402d216d8b1fa2b9f8e18b0dc1b5c81f96e0827c6cc83eba6e2205d4", + "0xc63b7b73283233470a85ad7ec28f772b7571c0f6ba90d506999809c2e25a7da6", + "0x82c7bc265be8c8190319e29a314f8c32e62b98bbc9c39defff06a42b34557191", + "0xeb223764963bceacbb06d72a3697801c2460ddf95b2ec410d2641d69249d466f" + ], + "GNOSIS_PROTOCOL_RELAYER": [ + "0xeba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b498", + "0x1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30" + ], + "BLABS_VEBAL_MULTISIG": [ + "0x802db13f34b039826402f87748c166a94c8130bf894f8af7e1144c874b36b76e", + "0xbfa133e7b0ebe7bf8b3f11a17a38c0f4492b428e4fb7fc8b509da63189247b06", + "0x79922681fd17c90b4f3409d605f5b059ffcbcef7b5440321ae93b87f3b5c1c78" + ], + "0xdcdbf71a870cc60c6f9b621e28a7d3ffd6dd4965": [ + "0x1282ab709b2b70070f829c46bc36f76b32ad4989fecb2fcb09a1b3ce00bbfc30", + "0xc149e88b59429ded7f601ab52ecd62331cac006ae07c16543439ed138dcb8d34", + "0x7b8a1d293670124924a0f532213753b89db10bde737249d4540e9a03657d1aff", + "0x78ad1b68d148c070372f8643c4648efbb63c6a8a338f3c24714868e791367653", + "0xeba777d811cd36c06d540d7ff2ed18ed042fd67bbf7c9afcf88c818c7ee6b498" + ], + "GAUNTLET_FEE_SETTER": [ + "0x36e042f590f2c5d0d8959cc373c8b1681f70f84e9656be8dd0eae652e01de4eb", + "0x78e9adfe5f05d7114a59d0870d78971192f871f57bb36e2aff2edbe75d425844", + "0xc065d550fa98abc242b6baf98e7b2063590675f1ddd81bdb9ea8d8f5c5d52f98", + "0x6c3a14f10cbcc5a3f4d0e4e8ad279e7a842735ab188e2b13fb84c6542cc3320c", + "0xcf5e03a737e4f5ba6d13e23f893a1e0255b362d8ce22e9568e1565fcf92789c7", + "0x7b09f4b61ccfe85436161b0223489b187d9f9158c542b5e6105df147afc78aca", + "0x15d3918ca8f9895d8906a780f5f402d32707bada7b1b5e7b21b7351257103a35", + "0x3697d13ee45583cf9c2c64a978ab5886bcd07ec2b851efbea2fced982b8f9596" + ], + "0xeb151668006cd04dadd098afd0a82e78f77076c3": [ + "0x96932b9555c49f1a3a7fb90d4b1ea803f16e02e14a6b942202a84e5f6b65d5c4" + ], + "SWAP_FEE_CONTROLLER_BALLER_MULTISIG": [ + "0x11562115fbcf4955e097732f59969867f1cb458a8cbd648231b0ffae14c800de", + "0xcad4ec1d64970817394bee6f75af4645fb72ba5b88902c4c155ce82aab0a3a5a", + "0xf8ab8bdb4497d157053d2f796e50c33e6fff3d586b6db6880ab12eff1d907b2b", + "0xf27148d3f1da6319bd754a52acd00b2fc3fa6474241d2398c6d58e8ac0cd9539", + "0xef008574ca41f2b6033a54a73ad6adc382165acd85b6f76f8456d9946b299a16", + "0x94611f33019f04ed070e076bbacb9ff5c5fe03d7184bef4026e1ee669d3b623e", + "0x7fad14fae895c80a37148957909942740cfbc0ddc5676b975d9893577ba7cd17", + "0xc30e3272c4933a085c95b84fca44f1a9b3d43e3e560b7b1fac0a6b2c9bbda16f", + "0xd4f0c40da2129d4b1aba541e693e03b92a323a66f649257a258fe6e4ea331b52", + "0xe5a9dede86018292d3cd547db825db489579eedbf2eebd3694ab93e912c1fae5" + ] +} \ No newline at end of file diff --git a/pkg/permissions/permissions/functions.json b/pkg/permissions/permissions/functions.json new file mode 100644 index 0000000000..55c8c7aa7a --- /dev/null +++ b/pkg/permissions/permissions/functions.json @@ -0,0 +1,612 @@ +{ + "0x02f35da6a02017154367bc4d47bb6c7d06c7533b": [ + { + "taskId": "20211208-aave-linear-pool", + "contractName": "AaveLinearPool", + "signature": "setPaused(bool)", + "useAdaptor": false + }, + { + "taskId": "20220413-arbitrum-root-gauge-factory", + "contractName": "ArbitrumRootGaugeFactory", + "signature": "setArbitrumFees(uint64,uint64,uint64)", + "useAdaptor": false + }, + { + "taskId": "20220325-gauge-controller", + "contractName": "VotingEscrow", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220325-gauge-controller", + "contractName": "GaugeController", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220325-single-recipient-gauge-factory", + "contractName": "SingleRecipientGauge", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220413-arbitrum-root-gauge-factory", + "contractName": "ArbitrumRootGauge", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220413-polygon-root-gauge-factory", + "contractName": "PolygonRootGauge", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220420-fee-distributor", + "contractName": "FeeDistributor", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220628-optimism-root-gauge-factory", + "contractName": "OptimismRootGauge", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220714-fee-distributor-v2", + "contractName": "FeeDistributor", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220823-optimism-root-gauge-factory-v2", + "contractName": "OptimismRootGauge", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220823-arbitrum-root-gauge-factory-v2", + "contractName": "ArbitrumRootGauge", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220823-polygon-root-gauge-factory-v2", + "contractName": "PolygonRootGauge", + "signature": "checkpoint()", + "useAdaptor": true + }, + { + "taskId": "20220628-optimism-root-gauge-factory", + "contractName": "OptimismRootGaugeFactory", + "signature": "setOptimismGasLimit(uint32)", + "useAdaptor": false + }, + { + "taskId": "20211208-stable-phantom-pool", + "contractName": "StablePhantomPool", + "signature": "setPaused(bool)", + "useAdaptor": false + } + ], + "DAO_MULTISIG": [ + { + "taskId": "20220325-ve-delegation", + "contractName": "VotingEscrowDelegationProxy", + "signature": "setDelegation(address)", + "useAdaptor": false + }, + { + "taskId": "20220420-smart-wallet-checker", + "contractName": "SmartWalletChecker", + "signature": "denylistAddress(address)", + "useAdaptor": false + }, + { + "taskId": "20220325-mainnet-gauge-factory", + "contractName": "LiquidityGaugeV5", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220325-single-recipient-gauge-factory", + "contractName": "SingleRecipientGauge", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220413-arbitrum-root-gauge-factory", + "contractName": "ArbitrumRootGauge", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220413-polygon-root-gauge-factory", + "contractName": "PolygonRootGauge", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220628-optimism-root-gauge-factory", + "contractName": "OptimismRootGauge", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220822-mainnet-gauge-factory-v2", + "contractName": "LiquidityGaugeV5", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220823-optimism-root-gauge-factory-v2", + "contractName": "OptimismRootGauge", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220823-arbitrum-root-gauge-factory-v2", + "contractName": "ArbitrumRootGauge", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220823-polygon-root-gauge-factory-v2", + "contractName": "PolygonRootGauge", + "signature": "killGauge()", + "useAdaptor": true + }, + { + "taskId": "20220725-protocol-fee-percentages-provider", + "contractName": "ProtocolFeePercentagesProvider", + "signature": "setFeeTypePercentage(uint256,uint256)", + "useAdaptor": false + }, + { + "taskId": "20220420-smart-wallet-checker", + "contractName": "SmartWalletChecker", + "signature": "allowlistAddress(address)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "ProtocolFeesCollector", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + } + ], + "0x170027069fd114bff2f57b0fc796df93290c02a6": [ + { + "taskId": "20210418-weighted-pool", + "contractName": "WeightedPool", + "signature": "setPaused(bool)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "setPaused(bool)", + "useAdaptor": false + } + ], + "0x239e55f427d44c3cc793f49bfb507ebe76638a2b": [ + { + "taskId": "20220325-balancer-token-admin", + "contractName": "BalancerTokenAdmin", + "signature": "mint(address,uint256)", + "useAdaptor": false + } + ], + "0x2536dfeecb7a0397cf98edada8486254533b1afa": [ + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "joinPool(bytes32,address,address,(address[],uint256[],bytes,bool))", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "swap((bytes32,uint8,address,address,uint256,bytes),(address,bool,address,bool),uint256,uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "batchSwap(uint8,(bytes32,uint256,uint256,uint256,bytes)[],address[],(address,bool,address,bool),int256[],uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "setRelayerApproval(address,address,bool)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "manageUserBalance((uint8,address,uint256,address,address)[])", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "exitPool(bytes32,address,address,(address[],uint256[],bytes,bool))", + "useAdaptor": false + } + ], + "0x2ffb7b215ae7f088ec2530c7aa8e1b24e398f26a": [ + { + "taskId": "20220325-gauge-controller", + "contractName": "GaugeController", + "signature": "add_gauge(address,int128)", + "useAdaptor": true + } + ], + "0x5ef4c5352882b10893b70dbcaa0c000965bd23c5": [ + { + "taskId": "20210418-vault", + "contractName": "ProtocolFeesCollector", + "signature": "withdrawCollectedFees(address[],uint256[],address)", + "useAdaptor": false + } + ], + "LINEAR_POOL_CONTROLLER_BALLER_MULTISIG": [ + { + "taskId": "20211208-stable-phantom-pool", + "contractName": "StablePhantomPool", + "signature": "setTokenRateCacheDuration(address,uint256)", + "useAdaptor": false + }, + { + "taskId": "20211208-aave-linear-pool", + "contractName": "AaveLinearPool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20211208-aave-linear-pool", + "contractName": "AaveLinearPool", + "signature": "setTargets(uint256,uint256)", + "useAdaptor": false + } + ], + "TREASURY_MULTISIG": [ + { + "taskId": "20220517-protocol-fee-withdrawer", + "contractName": "ProtocolFeesWithdrawer", + "signature": "withdrawCollectedFees(address[],uint256[],address)", + "useAdaptor": false + } + ], + "0x886a3ec7bcc508b8795990b60fa21f85f9db7948": [ + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "swap((bytes32,uint8,address,address,uint256,bytes),(address,bool,address,bool),uint256,uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "joinPool(bytes32,address,address,(address[],uint256[],bytes,bool))", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "batchSwap(uint8,(bytes32,uint256,uint256,uint256,bytes)[],address[],(address,bool,address,bool),int256[],uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "manageUserBalance((uint8,address,uint256,address,address)[])", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "setRelayerApproval(address,address,bool)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "exitPool(bytes32,address,address,(address[],uint256[],bytes,bool))", + "useAdaptor": false + } + ], + "0x97207b095e4d5c9a6e4cfbfcd2c3358e03b90c4a": [ + { + "taskId": "20210418-vault", + "contractName": "ProtocolFeesCollector", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "ProtocolFeesCollector", + "signature": "setFlashLoanFeePercentage(uint256)", + "useAdaptor": false + } + ], + "EMERGENCY_SUBDAO_MULTISIG": [ + { + "taskId": "20220817-aave-rebalanced-linear-pool", + "contractName": "AaveLinearPool", + "signature": "pause()", + "useAdaptor": false + }, + { + "taskId": "20220906-composable-stable-pool", + "contractName": "ComposableStablePool", + "signature": "pause()", + "useAdaptor": false + }, + { + "taskId": "20220817-aave-rebalanced-linear-pool", + "contractName": "AaveLinearPool", + "signature": "unpause()", + "useAdaptor": false + }, + { + "taskId": "20220908-weighted-pool-v2", + "contractName": "WeightedPool", + "signature": "pause()", + "useAdaptor": false + }, + { + "taskId": "20220906-composable-stable-pool", + "contractName": "ComposableStablePool", + "signature": "unpause()", + "useAdaptor": false + }, + { + "taskId": "20220517-protocol-fee-withdrawer", + "contractName": "ProtocolFeesWithdrawer", + "signature": "denylistToken(address)", + "useAdaptor": false + }, + { + "taskId": "20220908-weighted-pool-v2", + "contractName": "WeightedPool", + "signature": "unpause()", + "useAdaptor": false + } + ], + "0xac9f49ef3ab0bbc929f7b1bb0a17e1fca5786251": [ + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "manageUserBalance((uint8,address,uint256,address,address)[])", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "swap((bytes32,uint8,address,address,uint256,bytes),(address,bool,address,bool),uint256,uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "batchSwap(uint8,(bytes32,uint256,uint256,uint256,bytes)[],address[],(address,bool,address,bool),int256[],uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "joinPool(bytes32,address,address,(address[],uint256[],bytes,bool))", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "exitPool(bytes32,address,address,(address[],uint256[],bytes,bool))", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "setRelayerApproval(address,address,bool)", + "useAdaptor": false + } + ], + "LM_MULTISIG": [ + { + "taskId": "20220628-gauge-adder-v2", + "contractName": "GaugeAdder", + "signature": "addPolygonGauge(address)", + "useAdaptor": false + }, + { + "taskId": "20220628-gauge-adder-v2", + "contractName": "GaugeAdder", + "signature": "addEthereumGauge(address)", + "useAdaptor": false + }, + { + "taskId": "20220325-gauge-adder", + "contractName": "GaugeAdder", + "signature": "addArbitrumGauge(address)", + "useAdaptor": false + }, + { + "taskId": "20220325-gauge-adder", + "contractName": "GaugeAdder", + "signature": "addEthereumGauge(address)", + "useAdaptor": false + }, + { + "taskId": "20220628-gauge-adder-v2", + "contractName": "GaugeAdder", + "signature": "addOptimismGauge(address)", + "useAdaptor": false + }, + { + "taskId": "20220628-gauge-adder-v2", + "contractName": "GaugeAdder", + "signature": "addArbitrumGauge(address)", + "useAdaptor": false + }, + { + "taskId": "20220325-gauge-adder", + "contractName": "GaugeAdder", + "signature": "addPolygonGauge(address)", + "useAdaptor": false + } + ], + "GNOSIS_PROTOCOL_RELAYER": [ + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "manageUserBalance((uint8,address,uint256,address,address)[])", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "batchSwap(uint8,(bytes32,uint256,uint256,uint256,bytes)[],address[],(address,bool,address,bool),int256[],uint256)", + "useAdaptor": false + } + ], + "BLABS_VEBAL_MULTISIG": [ + { + "taskId": "20220325-bal-token-holder-factory", + "contractName": "BALTokenHolder", + "signature": "function withdrawFunds(address,uint256)", + "useAdaptor": false + } + ], + "0xdcdbf71a870cc60c6f9b621e28a7d3ffd6dd4965": [ + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "batchSwap(uint8,(bytes32,uint256,uint256,uint256,bytes)[],address[],(address,bool,address,bool),int256[],uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "exitPool(bytes32,address,address,(address[],uint256[],bytes,bool))", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "swap((bytes32,uint8,address,address,uint256,bytes),(address,bool,address,bool),uint256,uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "joinPool(bytes32,address,address,(address[],uint256[],bytes,bool))", + "useAdaptor": false + }, + { + "taskId": "20210418-vault", + "contractName": "Vault", + "signature": "manageUserBalance((uint8,address,uint256,address,address)[])", + "useAdaptor": false + } + ], + "GAUNTLET_FEE_SETTER": [ + { + "taskId": "20211208-stable-phantom-pool", + "contractName": "StablePhantomPool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20220908-weighted-pool-v2", + "contractName": "WeightedPool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-weighted-pool", + "contractName": "WeightedPool2Tokens", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20220906-composable-stable-pool", + "contractName": "ComposableStablePool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20220609-stable-pool-v2", + "contractName": "StablePool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20210624-stable-pool", + "contractName": "StablePool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20210727-meta-stable-pool", + "contractName": "MetaStablePool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20210418-weighted-pool", + "contractName": "WeightedPool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + } + ], + "0xeb151668006cd04dadd098afd0a82e78f77076c3": [ + { + "taskId": "20220325-balancer-token-admin", + "contractName": "BalancerTokenAdmin", + "signature": "activate()", + "useAdaptor": false + } + ], + "SWAP_FEE_CONTROLLER_BALLER_MULTISIG": [ + { + "taskId": "20220609-stable-pool-v2", + "contractName": "StablePool", + "signature": "startAmplificationParameterUpdate(uint256,uint256)", + "useAdaptor": false + }, + { + "taskId": "20220906-composable-stable-pool", + "contractName": "ComposableStablePool", + "signature": "startAmplificationParameterUpdate(uint256,uint256)", + "useAdaptor": false + }, + { + "taskId": "20220817-aave-rebalanced-linear-pool", + "contractName": "AaveLinearPool", + "signature": "setTargets(uint256,uint256)", + "useAdaptor": false + }, + { + "taskId": "20220817-aave-rebalanced-linear-pool", + "contractName": "AaveLinearPool", + "signature": "setSwapFeePercentage(uint256)", + "useAdaptor": false + }, + { + "taskId": "20220906-composable-stable-pool", + "contractName": "ComposableStablePool", + "signature": "stopAmplificationParameterUpdate()", + "useAdaptor": false + }, + { + "taskId": "20220609-stable-pool-v2", + "contractName": "StablePool", + "signature": "stopAmplificationParameterUpdate()", + "useAdaptor": false + } + ] +} \ No newline at end of file diff --git a/pkg/permissions/permissions/unrecognised.json b/pkg/permissions/permissions/unrecognised.json new file mode 100644 index 0000000000..2cc1c6cb0c --- /dev/null +++ b/pkg/permissions/permissions/unrecognised.json @@ -0,0 +1,23 @@ +{ + "DAO_MULTISIG": [ + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "EMERGENCY_SUBDAO_MULTISIG": [ + "0x367e95c6cc9f3041f3c6ee21b06ef8992a82318a6b2adbbfb6af3ee601769a30", + "0xfef90c64be79cb170a20e526196e7c8f2f37f441ae85c945c18a91a64777d309" + ], + "LM_MULTISIG": [ + "0x590e300e371ba81baff1c912e578fdecbfa490f39994607a18ee692ab942f846" + ], + "BLABS_VEBAL_MULTISIG": [ + "0x802db13f34b039826402f87748c166a94c8130bf894f8af7e1144c874b36b76e", + "0xbfa133e7b0ebe7bf8b3f11a17a38c0f4492b428e4fb7fc8b509da63189247b06", + "0x79922681fd17c90b4f3409d605f5b059ffcbcef7b5440321ae93b87f3b5c1c78" + ], + "SWAP_FEE_CONTROLLER_BALLER_MULTISIG": [ + "0x11562115fbcf4955e097732f59969867f1cb458a8cbd648231b0ffae14c800de", + "0xf8ab8bdb4497d157053d2f796e50c33e6fff3d586b6db6880ab12eff1d907b2b", + "0x94611f33019f04ed070e076bbacb9ff5c5fe03d7184bef4026e1ee669d3b623e", + "0xd4f0c40da2129d4b1aba541e693e03b92a323a66f649257a258fe6e4ea331b52" + ] +} \ No newline at end of file diff --git a/pkg/permissions/scripts/getCallableFunctions.ts b/pkg/permissions/scripts/getCallableFunctions.ts new file mode 100644 index 0000000000..190a06b0f8 --- /dev/null +++ b/pkg/permissions/scripts/getCallableFunctions.ts @@ -0,0 +1,65 @@ +import fs from 'fs'; +import path from 'path'; +import { ActionIdInfo, ContractActionIdData, getActionIdFunctions, safeReadJsonFile } from '../src/actionIds'; +import { getAccountLabel } from '../src/labelling'; + +const funcsPath = path.join(__dirname, '../../deployments/action-ids/mainnet/action-ids.json'); + +const actionIdFunctions = getActionIdFunctions(safeReadJsonFile>(funcsPath)); + +const specialCasedActionIds: Record = { + // Withdraw permission over BALTokenHolder for veBAL gauge. + '0x79922681fd17c90b4f3409d605f5b059ffcbcef7b5440321ae93b87f3b5c1c78': [ + { + taskId: '20220325-bal-token-holder-factory', + contractName: 'BALTokenHolder', + signature: 'function withdrawFunds(address,uint256)', + useAdaptor: false, + }, + ], +}; + +const ignoredActionIds: string[] = [ + // Root permission. This is being removed as part of the migration to TimelockAuthorizer. + '0x0000000000000000000000000000000000000000000000000000000000000000', + // Unknown permissions. Should be revoked/renounced before migration. + // Granted in https://forum.balancer.fi/t/bip-49-composablestable-and-aavelinearpools-permission-granting/3631 + // but doesn't correspond to anything onchain. + '0x11562115fbcf4955e097732f59969867f1cb458a8cbd648231b0ffae14c800de', + '0xf8ab8bdb4497d157053d2f796e50c33e6fff3d586b6db6880ab12eff1d907b2b', + '0x94611f33019f04ed070e076bbacb9ff5c5fe03d7184bef4026e1ee669d3b623e', + '0xd4f0c40da2129d4b1aba541e693e03b92a323a66f649257a258fe6e4ea331b52', + '0x367e95c6cc9f3041f3c6ee21b06ef8992a82318a6b2adbbfb6af3ee601769a30', + '0xfef90c64be79cb170a20e526196e7c8f2f37f441ae85c945c18a91a64777d309', + // Withdraw permission over unused BALTokenHolders + // LM committee BALTokenHolder + '0x590e300e371ba81baff1c912e578fdecbfa490f39994607a18ee692ab942f846', + // Polygon BALTokenHolder + '0x802db13f34b039826402f87748c166a94c8130bf894f8af7e1144c874b36b76e', + // Arbitrum BALTokenHolder + '0xbfa133e7b0ebe7bf8b3f11a17a38c0f4492b428e4fb7fc8b509da63189247b06', +]; + +const main = async () => { + const inputPath = path.join(__dirname, '../permissions/actionIds.json'); + const userPermissions = safeReadJsonFile(inputPath); + + const callableFunctions = Object.fromEntries( + Object.entries(userPermissions).map(([user, actionIds]) => [ + getAccountLabel(user), + actionIds + .filter((actionId) => !ignoredActionIds.includes(actionId)) + .flatMap((actionId) => { + const actionIdInfo = actionIdFunctions[actionId] ?? specialCasedActionIds[actionId]; + if (actionIdInfo === undefined) throw new Error(`Unknown action id: ${actionId}`); + return actionIdInfo; + }), + ]) + ); + + const filePath = path.join(__dirname, '../permissions/functions.json'); + + fs.writeFileSync(filePath, JSON.stringify(callableFunctions, null, 2)); +}; + +main(); diff --git a/pkg/permissions/scripts/getPermissionedAccounts.ts b/pkg/permissions/scripts/getPermissionedAccounts.ts new file mode 100644 index 0000000000..8931ca2463 --- /dev/null +++ b/pkg/permissions/scripts/getPermissionedAccounts.ts @@ -0,0 +1,21 @@ +import fs from 'fs'; +import path from 'path'; +import { getAccountsWithPermissions } from '../src/accounts'; +import { getAccountLabel } from '../src/labelling'; + +const main = async () => { + const userPermissions = await getAccountsWithPermissions(); + + const flattenedUserPermissions = Object.fromEntries( + userPermissions.map((user) => [ + getAccountLabel(user.id), + user.permissions.flatMap((permission) => permission.action.id), + ]) + ); + + const filePath = path.join(__dirname, '../permissions/actionIds.json'); + + fs.writeFileSync(filePath, JSON.stringify(flattenedUserPermissions, null, 2)); +}; + +main(); diff --git a/pkg/permissions/scripts/getUnrecognisedActionIds.ts b/pkg/permissions/scripts/getUnrecognisedActionIds.ts new file mode 100644 index 0000000000..06155b5ba7 --- /dev/null +++ b/pkg/permissions/scripts/getUnrecognisedActionIds.ts @@ -0,0 +1,28 @@ +import fs from 'fs'; +import path from 'path'; +import { ContractActionIdData, getActionIdFunctions, safeReadJsonFile } from '../src/actionIds'; +import { getAccountLabel } from '../src/labelling'; + +const funcsPath = path.join(__dirname, '../../deployments/action-ids/mainnet/action-ids.json'); + +const actionIdFunctions = getActionIdFunctions(safeReadJsonFile>(funcsPath)); + +const main = async () => { + const inputPath = path.join(__dirname, '../permissions/actionIds.json'); + const userPermissions = safeReadJsonFile(inputPath); + + const callableFunctions = Object.fromEntries( + Object.entries(userPermissions) + .map(([user, actionIds]) => [ + getAccountLabel(user), + actionIds.filter((actionId) => actionIdFunctions[actionId] == undefined), + ]) + .filter(([, actionIds]) => actionIds.length > 0) + ); + + const filePath = path.join(__dirname, '../permissions/unrecognised.json'); + + fs.writeFileSync(filePath, JSON.stringify(callableFunctions, null, 2)); +}; + +main(); diff --git a/pkg/permissions/src/accounts.ts b/pkg/permissions/src/accounts.ts new file mode 100644 index 0000000000..9ddf7ee30e --- /dev/null +++ b/pkg/permissions/src/accounts.ts @@ -0,0 +1,35 @@ +import fetch, { Response } from 'node-fetch'; +import { Account } from './types'; + +export const getAccountsWithPermissions = async (): Promise => { + const response: Response = await fetch('https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-authorizer', { + method: 'POST', + + headers: { + 'Content-Type': 'application/json', + }, + + body: JSON.stringify({ + query: `{ + accounts(first: 500) { + id + permissions { + action { + id + } + } + } + }`, + }), + }); + + const { + data: { accounts }, + }: { data: { accounts: Account[] } } = await response.json(); + + // The subgraph response also includes accounts which once had permissions which have since been revoked. + // We filter these out as they're not interesting. + const accountsWithPermissions = accounts.filter((acc) => acc.permissions.length > 0); + + return accountsWithPermissions; +}; diff --git a/pkg/permissions/src/actionIds.ts b/pkg/permissions/src/actionIds.ts new file mode 100644 index 0000000000..a5beb3097f --- /dev/null +++ b/pkg/permissions/src/actionIds.ts @@ -0,0 +1,39 @@ +import fs from 'fs'; +import path from 'path'; + +export const ACTION_ID_DIRECTORY = path.join(__dirname, '../../deployments/action-ids'); + +export type ContractActionIdData = { useAdaptor: boolean; factoryOutput?: string; actionIds: Record }; +export type ActionIdInfo = { + taskId: string; + contractName: string; + signature: string; + useAdaptor: boolean; +}; + +export function safeReadJsonFile(filePath: string): Record { + const fileExists = fs.existsSync(filePath) && fs.statSync(filePath).isFile(); + + return fileExists ? JSON.parse(fs.readFileSync(filePath).toString()) : {}; +} + +export function getActionIdFunctions( + actionIdFileContents: Record> +): Record { + // Reverse the mapping of `contractName -> signature -> actionId` to be `actionId -> [contractName, signature][]`. + // This simplifies checking for duplicate actionIds to just reading the length of the arrays. + return Object.entries(actionIdFileContents) + .flatMap(([taskId, taskData]) => + Object.entries(taskData).flatMap(([contractName, contractData]) => + Object.entries(contractData.actionIds).map<[string, ActionIdInfo]>(([signature, actionId]) => [ + actionId, + { taskId, contractName, signature, useAdaptor: contractData.useAdaptor }, + ]) + ) + ) + .reduce((acc: Record, [actionId, actionIdInfo]) => { + acc[actionId] = acc[actionId] ?? []; + acc[actionId].push(actionIdInfo); + return acc; + }, {}); +} diff --git a/pkg/permissions/src/labelling.ts b/pkg/permissions/src/labelling.ts new file mode 100644 index 0000000000..5459779afd --- /dev/null +++ b/pkg/permissions/src/labelling.ts @@ -0,0 +1,5 @@ +import labelledAccounts from '../labelled-accounts/mainnet.json'; + +export const getAccountLabel = (address: string): string => { + return labelledAccounts[address as never] ?? address; +}; diff --git a/pkg/permissions/src/types.ts b/pkg/permissions/src/types.ts new file mode 100644 index 0000000000..d07731a356 --- /dev/null +++ b/pkg/permissions/src/types.ts @@ -0,0 +1,16 @@ +export interface Action { + id: string; + permissions: Permission[]; +} + +export interface Permission { + id: string; + account: Account; + action: Action; + txHash: string; +} + +export interface Account { + id: string; + permissions: Permission[]; +} diff --git a/pkg/permissions/tsconfig.json b/pkg/permissions/tsconfig.json new file mode 100644 index 0000000000..e3907a4b8f --- /dev/null +++ b/pkg/permissions/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "moduleResolution": "node", + "declaration": true, + "outDir": "dist", + "resolveJsonModule": true + }, + "include": ["src", "scripts"] +} diff --git a/yarn.lock b/yarn.lock index 94c63b7429..d203957494 100644 --- a/yarn.lock +++ b/yarn.lock @@ -367,6 +367,23 @@ __metadata: languageName: unknown linkType: soft +"@balancer-labs/v2-permissions@workspace:pkg/permissions": + version: 0.0.0-use.local + resolution: "@balancer-labs/v2-permissions@workspace:pkg/permissions" + dependencies: + "@types/node": ^14.14.31 + "@typescript-eslint/eslint-plugin": ^5.41.0 + "@typescript-eslint/parser": ^5.41.0 + chalk: ^4.1.2 + eslint: ^8.26.0 + eslint-plugin-prettier: ^4.2.1 + node-fetch: ^2.6.7 + prettier: ^2.7.1 + ts-node: ^10.9.1 + typescript: ^4.0.2 + languageName: unknown + linkType: soft + "@balancer-labs/v2-pool-linear@workspace:pkg/pool-linear": version: 0.0.0-use.local resolution: "@balancer-labs/v2-pool-linear@workspace:pkg/pool-linear"