From 6e195314f72802a4404e758df3224373eca7e5b2 Mon Sep 17 00:00:00 2001 From: Miao ZhiCheng Date: Fri, 6 Sep 2024 19:05:21 +0300 Subject: [PATCH] GDA Pool Permission (#2010) --- packages/ethereum-contracts/CHANGELOG.md | 4 ++++ .../gdav1/GeneralDistributionAgreementV1.sol | 8 ++++++-- .../gdav1/GeneralDistributionAgreement.t.sol | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/ethereum-contracts/CHANGELOG.md b/packages/ethereum-contracts/CHANGELOG.md index 82dac18b5f..eaf48fb06a 100644 --- a/packages/ethereum-contracts/CHANGELOG.md +++ b/packages/ethereum-contracts/CHANGELOG.md @@ -9,6 +9,10 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm * `IUserDefinedMacro`: added a method `postCheck()` which allows to verify state changes after running the macro. +### Fixed + +* GDA Pools are not multi-tokens ready, added a permission check (#2010). + ## [v1.11.0] ### Breaking diff --git a/packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol b/packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol index 846967aec7..0583c2b7ed 100644 --- a/packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol +++ b/packages/ethereum-contracts/contracts/agreements/gdav1/GeneralDistributionAgreementV1.sol @@ -421,7 +421,9 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi newCtx = ctx; - if (_isPool(token, address(pool)) == false) { + if (_isPool(token, address(pool)) == false || + // Note: we do not support multi-tokens pools + pool.superToken() != token) { revert GDA_ONLY_SUPER_TOKEN_POOL(); } @@ -485,7 +487,9 @@ contract GeneralDistributionAgreementV1 is AgreementBase, TokenMonad, IGeneralDi int96 requestedFlowRate, bytes calldata ctx ) external override returns (bytes memory newCtx) { - if (_isPool(token, address(pool)) == false) { + if (_isPool(token, address(pool)) == false || + // Note: we do not support multi-tokens pools + pool.superToken() != token) { revert GDA_ONLY_SUPER_TOKEN_POOL(); } if (requestedFlowRate < 0) { diff --git a/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreement.t.sol b/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreement.t.sol index 122414dd95..64314f4e1e 100644 --- a/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreement.t.sol +++ b/packages/ethereum-contracts/test/foundry/agreements/gdav1/GeneralDistributionAgreement.t.sol @@ -204,6 +204,16 @@ contract GeneralDistributionAgreementV1IntegrationTest is FoundrySuperfluidTeste vm.stopPrank(); } + function testRevertDistributeFlowToPoolOfWrongToken(int96 requestedFlowRate) public { + vm.assume(requestedFlowRate >= 0); + vm.assume(requestedFlowRate < int96(type(int64).max)); + ISuperToken badToken = sfDeployer.deployNativeAssetSuperToken("Super Bad", "BADx"); + vm.startPrank(alice); + vm.expectRevert(IGeneralDistributionAgreementV1.GDA_ONLY_SUPER_TOKEN_POOL.selector); + badToken.distributeFlow(alice, ISuperfluidPool(bob), requestedFlowRate); + vm.stopPrank(); + } + function testRevertDistributeFromAnyAddressWhenNotAllowed(bool useForwarder) public { PoolConfig memory config = PoolConfig({ transferabilityForUnitsOwner: true, distributionFromAnyAddress: false }); ISuperfluidPool pool = _helperCreatePool(superToken, alice, alice, useForwarder, config); @@ -258,6 +268,15 @@ contract GeneralDistributionAgreementV1IntegrationTest is FoundrySuperfluidTeste vm.stopPrank(); } + function testRevertDistributeToPoolOfWrongToken(uint256 requestedAmount) public { + vm.assume(requestedAmount < uint256(type(uint128).max)); + ISuperToken badToken = sfDeployer.deployNativeAssetSuperToken("Super Bad", "BADx"); + vm.startPrank(alice); + vm.expectRevert(IGeneralDistributionAgreementV1.GDA_ONLY_SUPER_TOKEN_POOL.selector); + badToken.distributeToPool(alice, ISuperfluidPool(bob), requestedAmount); + vm.stopPrank(); + } + function testRevertDistributeForOthers(address signer, uint256 requestedAmount) public { ISuperfluidPool pool = _helperCreatePool(superToken, alice, alice, false, poolConfig); vm.assume(requestedAmount < uint256(type(uint128).max));