diff --git a/packages/ethereum-contracts/CHANGELOG.md b/packages/ethereum-contracts/CHANGELOG.md index eaf48fb06a..61135dd11a 100644 --- a/packages/ethereum-contracts/CHANGELOG.md +++ b/packages/ethereum-contracts/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ### Changed * `IUserDefinedMacro`: added a method `postCheck()` which allows to verify state changes after running the macro. +* `SuperfluidFrameworkDeployer` now also deploys and `MacroForwarder` and enables it as trusted forwarder. ### Fixed diff --git a/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol b/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol index 7d15408dd4..a8c769b773 100644 --- a/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol +++ b/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol @@ -33,6 +33,7 @@ import { CFAv1Library } from "../apps/CFAv1Library.sol"; import { IDAv1Library } from "../apps/IDAv1Library.sol"; import { IResolver } from "../interfaces/utils/IResolver.sol"; import { DMZForwarder } from "../utils/DMZForwarder.sol"; +import { MacroForwarder } from "../utils/MacroForwarder.sol"; /// @title Superfluid Framework Deployment Steps /// @author Superfluid @@ -66,6 +67,7 @@ contract SuperfluidFrameworkDeploymentSteps { CFAv1Forwarder cfaV1Forwarder; IDAv1Forwarder idaV1Forwarder; GDAv1Forwarder gdaV1Forwarder; + MacroForwarder macroForwarder; BatchLiquidator batchLiquidator; TOGA toga; } @@ -92,6 +94,7 @@ contract SuperfluidFrameworkDeploymentSteps { CFAv1Forwarder internal cfaV1Forwarder; IDAv1Forwarder internal idaV1Forwarder; GDAv1Forwarder internal gdaV1Forwarder; + MacroForwarder internal macroForwarder; // Other Peripheral Contracts TestResolver internal testResolver; @@ -121,6 +124,7 @@ contract SuperfluidFrameworkDeploymentSteps { cfaV1Forwarder: cfaV1Forwarder, idaV1Forwarder: idaV1Forwarder, gdaV1Forwarder: gdaV1Forwarder, + macroForwarder: macroForwarder, batchLiquidator: batchLiquidator, toga: toga }); @@ -224,6 +228,10 @@ contract SuperfluidFrameworkDeploymentSteps { // Deploy GDAv1Forwarder gdaV1Forwarder = GDAv1ForwarderDeployerLibrary.deploy(host); testGovernance.enableTrustedForwarder(host, ISuperfluidToken(address(0)), address(gdaV1Forwarder)); + + // Deploy MacroForwarder + macroForwarder = new MacroForwarder(host); + testGovernance.enableTrustedForwarder(host, ISuperfluidToken(address(0)), address(macroForwarder)); } else if (step == 5) {// PERIPHERAL CONTRACTS: SuperToken Logic and SuperTokenFactory Logic // Deploy canonical SuperToken logic contract superTokenLogic = SuperToken(SuperTokenDeployerLibrary.deploy( diff --git a/packages/ethereum-contracts/test/foundry/SuperfluidFrameworkDeployer.t.sol b/packages/ethereum-contracts/test/foundry/SuperfluidFrameworkDeployer.t.sol index 250b0367f8..abbfc3c1c9 100644 --- a/packages/ethereum-contracts/test/foundry/SuperfluidFrameworkDeployer.t.sol +++ b/packages/ethereum-contracts/test/foundry/SuperfluidFrameworkDeployer.t.sol @@ -21,6 +21,7 @@ contract SuperfluidFrameworkDeployerTest is FoundrySuperfluidTester { assertTrue(address(sf.cfaV1Forwarder) != address(0), "SFDeployer: cfaV1Forwarder not deployed"); assertTrue(address(sf.idaV1Forwarder) != address(0), "SFDeployer: idaV1Forwarder not deployed"); assertTrue(address(sf.gdaV1Forwarder) != address(0), "SFDeployer: gdaV1Forwarder not deployed"); + assertTrue(address(sf.macroForwarder) != address(0), "SFDeployer: macroForwarder not deployed"); assertTrue(address(sf.batchLiquidator) != address(0), "SFDeployer: batchLiquidator not deployed"); } diff --git a/packages/ethereum-contracts/test/foundry/utils/MacroForwarder.t.sol b/packages/ethereum-contracts/test/foundry/utils/MacroForwarder.t.sol index ac72df5219..f4b5d05cda 100644 --- a/packages/ethereum-contracts/test/foundry/utils/MacroForwarder.t.sol +++ b/packages/ethereum-contracts/test/foundry/utils/MacroForwarder.t.sol @@ -74,7 +74,7 @@ contract GoodMacro is IUserDefinedMacro { contract MultiFlowDeleteMacro is IUserDefinedMacro { error InsufficientReward(); - function buildBatchOperations(ISuperfluid host, bytes memory params, address msgSender) external override view + function buildBatchOperations(ISuperfluid host, bytes memory params, address /*msgSender*/) external override view returns (ISuperfluid.Operation[] memory operations) { IConstantFlowAgreementV1 cfa = IConstantFlowAgreementV1(address(host.getAgreementClass( @@ -82,7 +82,7 @@ contract MultiFlowDeleteMacro is IUserDefinedMacro { ))); // parse params - (ISuperToken token, address sender, address[] memory receivers, uint256 minBalanceAfter) = + (ISuperToken token, address sender, address[] memory receivers,) = abi.decode(params, (ISuperToken, address, address[], uint256)); // construct batch operations @@ -110,7 +110,7 @@ contract MultiFlowDeleteMacro is IUserDefinedMacro { return abi.encode(superToken, sender, receivers, minBalanceAfter); } - function postCheck(ISuperfluid host, bytes memory params, address msgSender) external view { + function postCheck(ISuperfluid /*host*/, bytes memory params, address msgSender) external view { // parse params (ISuperToken superToken,,, uint256 minBalanceAfter) = abi.decode(params, (ISuperToken, address, address[], uint256)); @@ -172,29 +172,19 @@ contract StatefulMacro is IUserDefinedMacro { // ============== Test Contract ============== contract MacroForwarderTest is FoundrySuperfluidTester { - MacroForwarder internal macroForwarder; - constructor() FoundrySuperfluidTester(5) { } - function setUp() public override { - super.setUp(); - macroForwarder = new MacroForwarder(sf.host); - vm.startPrank(address(sf.governance.owner())); - sf.governance.enableTrustedForwarder(sf.host, ISuperToken(address(0)), address(macroForwarder)); - vm.stopPrank(); - } - function testDummyMacro() external { NaugthyMacro m = new NaugthyMacro(false /* not naughty */); - macroForwarder.runMacro(IUserDefinedMacro(address(m)), new bytes(0)); + sf.macroForwarder.runMacro(IUserDefinedMacro(address(m)), new bytes(0)); } function testNaugtyMacro() external { NaugthyMacro m = new NaugthyMacro(true /* naughty */); vm.expectRevert(); // Note: need to cast the naughty macro - macroForwarder.runMacro(IUserDefinedMacro(address(m)), new bytes(0)); + sf.macroForwarder.runMacro(IUserDefinedMacro(address(m)), new bytes(0)); } function testGoodMacro() external { @@ -205,7 +195,7 @@ contract MacroForwarderTest is FoundrySuperfluidTester { vm.startPrank(admin); // NOTE! This is different from abi.encode(superToken, int96(42), [bob, carol]), // which is a fixed array: address[2]. - macroForwarder.runMacro(m, abi.encode(superToken, int96(42), recipients)); + sf.macroForwarder.runMacro(m, abi.encode(superToken, int96(42), recipients)); assertEq(sf.cfa.getNetFlow(superToken, bob), 42); assertEq(sf.cfa.getNetFlow(superToken, carol), 42); vm.stopPrank(); @@ -219,7 +209,7 @@ contract MacroForwarderTest is FoundrySuperfluidTester { vm.startPrank(admin); // NOTE! This is different from abi.encode(superToken, int96(42), [bob, carol]), // which is a fixed array: address[2]. - macroForwarder.runMacro(m, m.getParams(superToken, int96(42), recipients)); + sf.macroForwarder.runMacro(m, m.getParams(superToken, int96(42), recipients)); assertEq(sf.cfa.getNetFlow(superToken, bob), 42); assertEq(sf.cfa.getNetFlow(superToken, carol), 42); vm.stopPrank(); @@ -231,10 +221,10 @@ contract MacroForwarderTest is FoundrySuperfluidTester { recipients[1] = carol; StatefulMacro m = new StatefulMacro(); m.setConfig(StatefulMacro.Config( - macroForwarder, superToken, 42, recipients, dan + sf.macroForwarder, superToken, 42, recipients, dan )); vm.startPrank(admin); - macroForwarder.runMacro(m, new bytes(0)); + sf.macroForwarder.runMacro(m, new bytes(0)); assertEq(sf.cfa.getNetFlow(superToken, bob), 42); assertEq(sf.cfa.getNetFlow(superToken, carol), 42); vm.stopPrank(); @@ -254,7 +244,7 @@ contract MacroForwarderTest is FoundrySuperfluidTester { superToken.createFlow(recipients[i], 42); } // now batch-delete them - macroForwarder.runMacro(m, m.getParams(superToken, sender, recipients, 0)); + sf.macroForwarder.runMacro(m, m.getParams(superToken, sender, recipients, 0)); for (uint i = 0; i < recipients.length; ++i) { assertEq(sf.cfa.getNetFlow(superToken, recipients[i]), 0); @@ -284,9 +274,9 @@ contract MacroForwarderTest is FoundrySuperfluidTester { uint256 danBalanceBefore = superToken.balanceOf(dan); // unreasonable reward expectation: post check fails vm.expectRevert(MultiFlowDeleteMacro.InsufficientReward.selector); - macroForwarder.runMacro(m, abi.encode(superToken, alice, recipients, danBalanceBefore + 1e24)); + sf.macroForwarder.runMacro(m, abi.encode(superToken, alice, recipients, danBalanceBefore + 1e24)); // reasonable reward expectation: post check passes - macroForwarder.runMacro(m, abi.encode(superToken, alice, recipients, danBalanceBefore + (uint256(uint96(flowRate)) * 600))); + sf.macroForwarder.runMacro(m, abi.encode(superToken, alice, recipients, danBalanceBefore + (uint256(uint96(flowRate)) * 600))); } } \ No newline at end of file