Skip to content

Commit 8799973

Browse files
authored
[ETHEREUM-CONTRACTS] Dedicated allowlist contract for SuperApp registration (#2083)
1 parent c5dfbab commit 8799973

File tree

19 files changed

+205
-52
lines changed

19 files changed

+205
-52
lines changed

packages/ethereum-contracts/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
99
- `SuperToken` now implements [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612) (permit extension for EIP-20 signed approvals).
1010
- `SuperfluidPool` now has additional methods `increaseMemberUnits` and `decreaseMemberUnits` which allow the pool admin to change member units parameterized with delta amounts.
1111

12+
### Changed
13+
- Curation of the SuperApp registration allowlist can now be delegated by governance to a newly added `ACL` contract.
14+
1215
### Breaking
1316
- `SuperfluidPool` does no longer mint and burn EIP-721 tokens (NFTs) on member unit updates. The gas overhead of this operation caused friction for integrations with other protocols (e.g. Uniswap V4).
1417

packages/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import {
4747
* `expectRevert` expects a revert in the next call.
4848
* If a revert is triggered by library code itself (vs by a call), `expectRevert` will thus not _see_ that.
4949
* Possible mitigations:
50-
* - avoid higher-level library methods which can themselves trigger reverts in tests where this is is an issue
50+
* - avoid higher-level library methods which can themselves trigger reverts in tests where this is an issue
5151
* - wrap the method invocation into an external helper method which you then invoke with `this.helperMethod()`,
5252
* which makes it an external call
5353
* Also be aware of other limitations, see

packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
/// Note: CustomSuperTokenBase is not included for people building CustomSuperToken.
1919
import { IERC20, IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
2020
import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
21+
import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
2122
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
2223
import { ISuperToken } from "./ISuperToken.sol";
2324
import { ISuperTokenFactory } from "./ISuperTokenFactory.sol";
@@ -29,10 +30,10 @@ import { IPoolMemberNFT } from "../agreements/gdav1/IPoolMemberNFT.sol";
2930
import { ISuperAgreement } from "./ISuperAgreement.sol";
3031
import { IConstantFlowAgreementV1 } from "../agreements/IConstantFlowAgreementV1.sol";
3132
import { IInstantDistributionAgreementV1 } from "../agreements/IInstantDistributionAgreementV1.sol";
32-
import {
33-
IGeneralDistributionAgreementV1,
34-
PoolConfig,
35-
PoolERC20Metadata
33+
import {
34+
IGeneralDistributionAgreementV1,
35+
PoolConfig,
36+
PoolERC20Metadata
3637
} from "../agreements/gdav1/IGeneralDistributionAgreementV1.sol";
3738
import { ISuperfluidPool } from "../agreements/gdav1/ISuperfluidPool.sol";
3839
/// Superfluid App interfaces:
@@ -658,6 +659,19 @@ interface ISuperfluid {
658659
// solhint-disable func-name-mixedcase
659660
function getERC2771Forwarder() external view returns(address);
660661

662+
// solhint-disable max-line-length
663+
/**
664+
* @dev returns the SimpleACL contract (currently used for SuperApp registration permissioning).
665+
* That contract implements the interface [IAccessControl](https://docs.openzeppelin.com/contracts/4.x/api/access#IAccessControl),
666+
* which provides the following functions:
667+
* - [hasRole(role, account)](https://docs.openzeppelin.com/contracts/4.x/api/access#IAccessControl-hasRole-bytes32-address-)
668+
* - [getRoleAdmin(role)](https://docs.openzeppelin.com/contracts/4.x/api/access#IAccessControl-getRoleAdmin-bytes32-)
669+
* - [grantRole(role, account)](https://docs.openzeppelin.com/contracts/4.x/api/access#IAccessControl-grantRole-bytes32-address-)
670+
* - [revokeRole(role, account)](https://docs.openzeppelin.com/contracts/4.x/api/access#IAccessControl-revokeRole-bytes32-address-)
671+
* - [renounceRole(role, account)](https://docs.openzeppelin.com/contracts/4.x/api/access#IAccessControl-renounceRole-bytes32-address-)
672+
*/
673+
function getSimpleACL() external view returns(IAccessControl);
674+
661675
/**************************************************************************
662676
* Function modifiers for access control and parameter validations
663677
*

packages/ethereum-contracts/contracts/mocks/CFAAppMocks.t.sol

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ contract ExclusiveInflowTestApp is SuperAppBase {
3636
// | SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP
3737
;
3838

39-
_host.registerAppWithKey(configWord, "");
39+
_host.registerApp(configWord);
4040
}
4141

4242
function afterAgreementCreated(
@@ -121,7 +121,7 @@ contract NonClosableOutflowTestApp is SuperAppBase {
121121
// | SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP
122122
;
123123

124-
_host.registerAppWithKey(configWord, "");
124+
_host.registerApp(configWord);
125125
}
126126

127127
function setupOutflow(
@@ -210,7 +210,7 @@ contract SelfDeletingFlowTestApp is SuperAppBase {
210210
| SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP
211211
;
212212

213-
_host.registerAppWithKey(configWord, "");
213+
_host.registerApp(configWord);
214214
}
215215

216216
function afterAgreementCreated(
@@ -267,7 +267,7 @@ contract ClosingOnUpdateFlowTestApp is SuperAppBase {
267267
| SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP
268268
;
269269

270-
_host.registerAppWithKey(configWord, "");
270+
_host.registerApp(configWord);
271271
}
272272

273273
function afterAgreementUpdated(
@@ -326,7 +326,7 @@ contract FlowExchangeTestApp is SuperAppBase {
326326
| SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP
327327
;
328328

329-
_host.registerAppWithKey(configWord, "");
329+
_host.registerApp(configWord);
330330
}
331331

332332
function afterAgreementCreated(

packages/ethereum-contracts/contracts/mocks/IDASuperAppTester.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ contract IDASuperAppTester is ISuperApp {
2626
uint32 indexId)
2727
{
2828
_host = host;
29-
_host.registerAppWithKey(configWord, "");
29+
_host.registerApp(configWord);
3030
_ida = ida;
3131
_token = token;
3232
_indexId = indexId;

packages/ethereum-contracts/contracts/mocks/MultiFlowTesterApp.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ contract MultiFlowTesterApp is SuperAppBase {
4141
SuperAppDefinitions.BEFORE_AGREEMENT_CREATED_NOOP |
4242
SuperAppDefinitions.BEFORE_AGREEMENT_TERMINATED_NOOP;
4343

44-
_host.registerAppWithKey(configWord, "");
44+
_host.registerApp(configWord);
4545
}
4646

4747
function _parseUserData(

packages/ethereum-contracts/contracts/mocks/StreamRedirector.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ contract StreamRedirector is SuperAppBase {
3333
token = _token;
3434
receiver = _receiver;
3535

36-
host.registerAppWithKey(configWord, "");
36+
host.registerApp(configWord);
3737
}
3838

3939
/**

packages/ethereum-contracts/contracts/mocks/SuperAppMocks.t.sol

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,14 @@ contract SuperAppMock is ISuperApp {
5252

5353
constructor(ISuperfluid host, uint256 configWord, bool doubleRegistration) {
5454
_host = host;
55-
_host.registerAppWithKey(configWord, "");
55+
_host.registerApp(configWord);
5656
if (doubleRegistration) {
57-
_host.registerAppWithKey(configWord, "");
57+
_host.registerApp(configWord);
5858
}
5959
_aux = new SuperAppMockAux();
6060
}
6161

6262
function tryRegisterApp(uint256 configWord) external {
63-
// @note this is deprecated keeping this here for testing/coverage
6463
_host.registerApp(configWord);
6564
}
6665

@@ -472,7 +471,7 @@ contract SuperAppMockReturningEmptyCtx {
472471

473472
constructor(ISuperfluid host) {
474473
_host = host;
475-
_host.registerAppWithKey(SuperAppDefinitions.APP_LEVEL_FINAL, "");
474+
_host.registerApp(SuperAppDefinitions.APP_LEVEL_FINAL);
476475
}
477476

478477
function beforeAgreementCreated(
@@ -533,7 +532,7 @@ contract SuperAppMockReturningInvalidCtx {
533532

534533
constructor(ISuperfluid host) {
535534
_host = host;
536-
_host.registerAppWithKey(SuperAppDefinitions.APP_LEVEL_FINAL, "");
535+
_host.registerApp(SuperAppDefinitions.APP_LEVEL_FINAL);
537536
}
538537

539538
function afterAgreementCreated(
@@ -574,7 +573,7 @@ contract SuperAppMock2ndLevel {
574573

575574
constructor(ISuperfluid host, SuperAppMock app, AgreementMock agreement) {
576575
_host = host;
577-
_host.registerAppWithKey(SuperAppDefinitions.APP_LEVEL_SECOND, "");
576+
_host.registerApp(SuperAppDefinitions.APP_LEVEL_SECOND);
578577
_app = app;
579578
_agreement = agreement;
580579
}
@@ -615,10 +614,9 @@ contract SuperAppMockWithRegistrationKey {
615614
}
616615
}
617616

618-
// An Super App that uses registerAppWithKey
617+
// An Super App that self-registers
619618
contract SuperAppMockUsingRegisterApp {
620619
constructor(ISuperfluid host, uint256 configWord) {
621-
// @note this is deprecated keeping this here for testing/coverage
622620
host.registerApp(configWord);
623621
}
624622
}
@@ -630,6 +628,7 @@ contract SuperAppMockNotSelfRegistering { }
630628
// Factory which allows anybody to deploy arbitrary contracts as app (do NOT allow this in a real factory!)
631629
contract SuperAppFactoryMock {
632630
function registerAppWithHost(ISuperfluid host, ISuperApp app, uint256 configWord) external {
631+
// @note this way of registering is DEPREACTED!
633632
host.registerAppByFactory(app, configWord);
634633
}
635634
}

packages/ethereum-contracts/contracts/mocks/SuperTokenLibraryV1Mock.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ contract SuperTokenLibraryCFASuperAppMock is SuperAppBase {
384384
SuperAppDefinitions.BEFORE_AGREEMENT_TERMINATED_NOOP |
385385
SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP;
386386

387-
host.registerAppWithKey(configWord, "");
387+
host.registerApp(configWord);
388388
}
389389

390390
function createFlow(ISuperToken token) external {

packages/ethereum-contracts/contracts/mocks/SuperfluidMock.t.sol

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { CallUtils } from "../libs/CallUtils.sol";
1212
contract SuperfluidUpgradabilityTester is Superfluid {
1313

1414
// 3_000_000 is the min callback gas limit used in a prod deployment
15-
constructor() Superfluid(false, false, 3_000_000, address(0), address(0))
15+
constructor() Superfluid(false, false, 3_000_000, address(0), address(0), address(0))
1616
// solhint-disable-next-line no-empty-blocks
1717
{
1818
}
@@ -135,10 +135,12 @@ contract SuperfluidMock is Superfluid {
135135
bool appWhiteListingEnabled,
136136
uint64 callbackGasLimit,
137137
address simpleForwarderAddress,
138-
address erc2771ForwarderAddress
138+
address erc2771ForwarderAddress,
139+
address simpleAclAddress
139140
)
140141
Superfluid(
141-
nonUpgradable, appWhiteListingEnabled, callbackGasLimit, simpleForwarderAddress, erc2771ForwarderAddress
142+
nonUpgradable, appWhiteListingEnabled, callbackGasLimit, simpleForwarderAddress, erc2771ForwarderAddress,
143+
simpleAclAddress
142144
)
143145
// solhint-disable-next-line no-empty-blocks
144146
{

0 commit comments

Comments
 (0)