Skip to content

Commit

Permalink
better plumbing (#1839)
Browse files Browse the repository at this point in the history
  • Loading branch information
d10r authored Feb 23, 2024
1 parent 8e9f7a5 commit a64e0de
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 42 deletions.
54 changes: 30 additions & 24 deletions packages/ethereum-contracts/contracts/apps/CFASuperAppBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,53 +32,59 @@ abstract contract CFASuperAppBase is ISuperApp {
error NotAcceptedSuperToken();

/**
* @dev Creates the contract and ties it to a Superfluid Host.
* @notice You also need to call `_initialize()` after construction.
* @dev Creates the contract tied to the provided Superfluid host
* @param host_ the Superfluid host the SuperApp belongs to
* @notice You also need to register the app with the host in order to enable callbacks.
* This can be done either by calling `selfRegister()` or by calling `host.registerApp()`.
*/
constructor(ISuperfluid host_) {
HOST = host_;
}

/**
* @dev Initializes the SuperApp with the provided settings
* @param activateOnCreated activates the callbacks for `createFlow`
* @param activateOnUpdated activates the callbacks for `updateFlow`
* @param activateOnDeleted activates the callbacks for `deleteFlow`
* @param selfRegister if true, the App shall register itself with the host.
* If false, the caller is reposible for calling `registerApp` on the host contract.
* No callbacks will be received as long as the App is not registered.
* @return configWord the `configWord` used or to be used in the `registerApp` call
* @dev Registers the SuperApp with its Superfluid host contract (self-registration)
* @param activateOnCreated if true, callbacks for `createFlow` will be activated
* @param activateOnUpdated if true, callbacks for `updateFlow` will be activated
* @param activateOnDeleted if true, callbacks for `deleteFlow` will be activated
*
* Note that if the App self-registers on a network with permissioned SuperApp registration,
* the tx.origin needs to be whitelisted for that transaction to succeed.
* Fore more details, see https://github.com/superfluid-finance/protocol-monorepo/wiki/Super-App-White-listing-Guide
* Note: if the App self-registers on a network with permissioned SuperApp registration,
* self-registration can be used only if the tx.origin (EOA) is whitelisted as deployer.
* If a whitelisted factory is used, it needs to call `host.registerApp()` itself.
* For more details, see https://github.com/superfluid-finance/protocol-monorepo/wiki/Super-App-White-listing-Guide
*/
function _initialize(
function selfRegister(
bool activateOnCreated,
bool activateOnUpdated,
bool activateOnDeleted,
bool selfRegister
) internal returns (uint256 configWord) {
bool activateOnDeleted
) public {
HOST.registerApp(getConfigWord(activateOnCreated, activateOnUpdated, activateOnDeleted));
}

/**
* @dev Convenience function to get the `configWord` for app registration when not using self-registration
* @param activateOnCreated if true, callbacks for `createFlow` will be activated
* @param activateOnUpdated if true, callbacks for `updateFlow` will be activated
* @param activateOnDeleted if true, callbacks for `deleteFlow` will be activated
* @return configWord the `configWord` encoding the provided settings
*/
function getConfigWord(
bool activateOnCreated,
bool activateOnUpdated,
bool activateOnDeleted
) public pure returns (uint256 configWord) {
configWord = SuperAppDefinitions.APP_LEVEL_FINAL
| SuperAppDefinitions.BEFORE_AGREEMENT_CREATED_NOOP;

if (!activateOnCreated) {
configWord |= SuperAppDefinitions.AFTER_AGREEMENT_CREATED_NOOP;
}

if (!activateOnUpdated) {
configWord |= SuperAppDefinitions.BEFORE_AGREEMENT_UPDATED_NOOP
| SuperAppDefinitions.AFTER_AGREEMENT_UPDATED_NOOP;
}

if (!activateOnDeleted) {
configWord |= SuperAppDefinitions.BEFORE_AGREEMENT_TERMINATED_NOOP
| SuperAppDefinitions.AFTER_AGREEMENT_TERMINATED_NOOP;
}

if (selfRegister) {
HOST.registerApp(configWord);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,10 @@ contract CFASuperAppBaseTester is CFASuperAppBase {
bool internal _restrictAcceptedSuperTokens;

constructor(
ISuperfluid host,
bool activateOnCreated,
bool activateOnUpdated,
bool activateOnDeleted,
bool selfRegister
ISuperfluid host
)
CFASuperAppBase(host)
{
_initialize(activateOnCreated, activateOnUpdated, activateOnDeleted, selfRegister);
lastUpdateHolder = 0; // appeasing linter
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract CrossStreamSuperApp is CFASuperAppBase {
int96 public prevFlowRate;

constructor(ISuperfluid host_, address z_) CFASuperAppBase(host_) {
_initialize(true, true, true, true);
selfRegister(true, true, true);
flowRecipient = z_;
}

Expand Down
28 changes: 18 additions & 10 deletions packages/ethereum-contracts/test/foundry/apps/CFASuperAppBase.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ contract CFASuperAppBaseTest is FoundrySuperfluidTester {
function setUp() public virtual override {
super.setUp();
vm.startPrank(admin);
superApp = new CFASuperAppBaseTester(sf.host, true, true, true, true);
superApp = new CFASuperAppBaseTester(sf.host);
superApp.selfRegister(true, true, true);
superAppAddress = address(superApp);
otherSuperToken = sfDeployer.deployPureSuperToken("FTT", "FTT", 1e27);
otherSuperToken.transfer(alice, 1e21);
Expand Down Expand Up @@ -58,30 +59,37 @@ contract CFASuperAppBaseTest is FoundrySuperfluidTester {
return callBackDefinitions;
}

function _deploySuperAppAndGetConfig(bool activateOnCreated, bool activateOnUpdated, bool activateOnDeleted, bool selfRegister)
function _deploySuperAppAndGetConfig(bool activateOnCreated, bool activateOnUpdated, bool activateOnDeleted)
internal
returns (CFASuperAppBaseTester, uint256 configWord)
{
CFASuperAppBaseTester mySuperApp =
new CFASuperAppBaseTester(sf.host, activateOnCreated, activateOnUpdated, activateOnDeleted, selfRegister);
CFASuperAppBaseTester mySuperApp = new CFASuperAppBaseTester(sf.host);
mySuperApp.selfRegister(activateOnCreated, activateOnUpdated, activateOnDeleted);
uint256 appConfig = _genManifest(activateOnCreated, activateOnUpdated, activateOnDeleted);
return (mySuperApp, appConfig);
}

function testOnFlagsSetAppManifest(bool activateOnCreated, bool activateOnUpdated, bool activateOnDeleted, bool selfRegister) public {
function testOnFlagsSetAppManifest(bool activateOnCreated, bool activateOnUpdated, bool activateOnDeleted) public {
//all onOperations
(CFASuperAppBaseTester mySuperApp, uint256 configWord) =
_deploySuperAppAndGetConfig(activateOnCreated, activateOnUpdated, activateOnDeleted, selfRegister);
if (!selfRegister) {
// this would revert if already registered
sf.host.registerApp(mySuperApp, configWord);
}
_deploySuperAppAndGetConfig(activateOnCreated, activateOnUpdated, activateOnDeleted);

(bool isSuperApp,, uint256 noopMask) = sf.host.getAppManifest(ISuperApp(mySuperApp));
configWord = configWord & SuperAppDefinitions.AGREEMENT_CALLBACK_NOOP_BITMASKS;
assertTrue(isSuperApp, "SuperAppBase: is superApp incorrect");
assertEq(noopMask, configWord, "SuperAppBase: noopMask != configWord");
}

function testRegistrationByFactory(bool activateOnCreated, bool activateOnUpdated, bool activateOnDeleted) public {
CFASuperAppBaseTester mySuperApp = new CFASuperAppBaseTester(sf.host);
sf.host.registerApp(
mySuperApp,
mySuperApp.getConfigWord(activateOnCreated, activateOnUpdated, activateOnDeleted)
);
(bool isSuperApp,,) = sf.host.getAppManifest(ISuperApp(mySuperApp));
assertTrue(isSuperApp, "SuperAppBase: is superApp incorrect");
}

function testAllowAllSuperTokensByDefault() public {
assertTrue(
superApp.isAcceptedSuperToken(superToken), "SuperAppBase: unrestricted | primary SuperToken accepted"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ contract FlowSplitter is CFASuperAppBase {
ISuperToken _acceptedSuperToken,
ISuperfluid _host
) CFASuperAppBase(_host) {
_initialize(true, true, true, true);
selfRegister(true, true, true);
mainReceiver = _mainReceiver;
sideReceiver = _sideReceiver;
sideReceiverPortion = _sideReceiverPortion;
Expand Down

0 comments on commit a64e0de

Please sign in to comment.