Skip to content

Commit

Permalink
merge dev
Browse files Browse the repository at this point in the history
  • Loading branch information
d10r committed Nov 21, 2024
2 parents 0b33f76 + 5b5c548 commit 05733de
Show file tree
Hide file tree
Showing 53 changed files with 344 additions and 206 deletions.
2 changes: 1 addition & 1 deletion packages/automation-contracts/autowrap/test/Manager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pragma solidity ^0.8.0;
import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/superfluid/SuperToken.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
import { Manager } from "./../contracts/Manager.sol";
import { IManager } from "./../contracts/interfaces/IManager.sol";
import { WrapStrategy } from "./../contracts/strategies/WrapStrategy.sol";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.0;

import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/superfluid/SuperToken.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
import { Manager } from "./../contracts/Manager.sol";
import { WrapStrategy } from "./../contracts/strategies/WrapStrategy.sol";
import { IStrategy } from "./../contracts/interfaces/IStrategy.sol";
Expand Down
2 changes: 1 addition & 1 deletion packages/automation-contracts/autowrap/test/WrapUp.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.0;

import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/superfluid/SuperToken.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
import { Manager } from "./../contracts/Manager.sol";
import { WrapStrategy } from "./../contracts/strategies/WrapStrategy.sol";
import { ISETH } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/tokens/ISETH.sol";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/in
import { FlowOperatorDefinitions } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import { IFlowScheduler } from "./../contracts/interface/IFlowScheduler.sol";
import { FlowScheduler } from "./../contracts/FlowScheduler.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
import { SuperToken } from "@superfluid-finance/ethereum-contracts/contracts/superfluid/SuperToken.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/in
import { FlowOperatorDefinitions } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import { FlowScheduler } from "./../contracts/FlowScheduler.sol";
import { FlowSchedulerResolver } from "./../contracts/FlowSchedulerResolver.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
import { SuperToken } from "@superfluid-finance/ethereum-contracts/contracts/superfluid/SuperToken.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/inte
import {FlowOperatorDefinitions} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import {IVestingSchedulerV2} from "./../contracts/interface/IVestingSchedulerV2.sol";
import {VestingSchedulerV2} from "./../contracts/VestingSchedulerV2.sol";
import {FoundrySuperfluidTester} from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.sol";
import {FoundrySuperfluidTester} from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
import {SuperTokenV1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import "forge-std/console2.sol";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/in
import { FlowOperatorDefinitions, ISuperfluid, BatchOperation, ISuperApp } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import { IVestingSchedulerV2 } from "./../contracts/interface/IVestingSchedulerV2.sol";
import { VestingSchedulerV2 } from "./../contracts/VestingSchedulerV2.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.sol";
import { FoundrySuperfluidTester } from "@superfluid-finance/ethereum-contracts/test/foundry/FoundrySuperfluidTester.t.sol";
import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
import { SafeMath } from "@openzeppelin/contracts/utils/math/SafeMath.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
Expand Down
16 changes: 11 additions & 5 deletions packages/ethereum-contracts/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,30 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

### Added
- Added functionality to `SuperTokenV1Library`, most notably `flowX` and `transferX`.
- `ISuperfluid.getERC2771Forwarder()`: to be used by batch call targets who want to use ERC-2771 for msg sender preservation.
- Utility contracts for forwarding of calls in the context of batch operations:
- `SimpleForwarder`: for forwarding arbitrary calls to arbitrary targets
- `ERC2771Forwarder`: for forwarding arbitrary calls to arbitrary targets with msg sender authenticated according to ERC-2771. Requires the target contract to recognize it as trusted forwarder.

### Breaking
- Removed `CFAv1Library`, superseded by `SuperTokenV1Library`.
- Removed `IDAv1Library` and IDA functionality from `SuperTokenV1Library`. IDA shall not be used anymore, the GDA covers all its functionality.
- Removed some methods from `SuperTokenV1Library` which don't belong to the token interface.
- Source file `SuperfluidFrameworkDeployer.sol` renamed to `SuperfluidFrameworkDeployer.t.sol`
- Source file `FoundrySuperfluidTester.sol` renamed to `FoundrySuperfluidTester.t.sol`

## [v1.11.1]

### Changed

* `MacroForwarder` made payable.
* `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.
* `deploy-test-environment.js` now deploys fUSDC (the underlying) with 6 decimals (instead of 18) to better resemble the actual USDC.
- `MacroForwarder` made payable.
- `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.
- `deploy-test-environment.js` now deploys fUSDC (the underlying) with 6 decimals (instead of 18) to better resemble the actual USDC.

### Fixed

* GDA Pools are not multi-tokens ready, added a permission check (#2010).
- GDA Pools are not multi-tokens ready, added a permission check (#2010).

## [v1.11.0]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,17 +231,22 @@ library BatchOperation {
*/
uint32 constant internal OPERATION_TYPE_SUPERFLUID_CALL_APP_ACTION = 2 + 200;
/**
* @dev DMZForwarder.forwardCall batch operation type
* @dev SimpleForwarder.forwardCall batch operation type
*
* Call spec:
* forwardCall(
* target,
* data
* )
* NOTE: This operation allows to make arbitrary calls to arbitrary targets.
* The calls are routed through a dedicated utility contract `SimpleForwarder`.
* This is important because the host contract has privileged access to other framework contracts,
* SuperTokens, SuperApps etc.
* Allowing arbitrary calls to arbitrary targets with the host as sender would thus be unsafe.
*/
uint32 constant internal OPERATION_TYPE_SIMPLE_FORWARD_CALL = 1 + 300;
/**
* @dev DMZForwarder.forward2771Call batch operation type
* @dev ERC2771Forwarder.forward2771Call batch operation type
*
* Call spec:
* forward2771Call(
Expand All @@ -250,17 +255,17 @@ library BatchOperation {
* data
* )
*
* NOTE: In the context of this operation, the `DZMForwarder` contract acts as the
* NOTE: In the context of this operation, the `ERC2771Forwarder` contract acts as the
* _trusted forwarder_ which must be trusted by the _recipient contract_ (operation target).
* It shall do so by dynamically looking up the DMZForwarder used by the host, like this:
* It shall do so by dynamically looking up the ERC2771Forwarder used by the host, like this:
*
* function isTrustedForwarder(address forwarder) public view returns(bool) {
* return forwarder == address(host.DMZ_FORWARDER());
* return forwarder == address(host.getERC2771Forwarder());
* }
*
* If used in the context of a `forwardBatchCall`, we effectively have a chaining/nesting
* of ERC-2771 calls where the host acts as _recipient contract_ of the enveloping 2771 call
* and the DMZForwarder acts as the _trusted forwarder_ of the nested 2771 call(s).
* and the ERC2771Forwarder acts as the _trusted forwarder_ of the nested 2771 call(s).
* That's why `msgSender` could be either the actual `msg.sender` (if using `batchCall`)
* or the relayed sender address (if using `forwardBatchCall`).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { ISuperApp } from "./ISuperApp.sol";
/// Superfluid governance
import { ISuperfluidGovernance } from "./ISuperfluidGovernance.sol";


/**
* @title Host interface
* @author Superfluid
Expand Down Expand Up @@ -645,6 +646,14 @@ interface ISuperfluid {
*/
function forwardBatchCall(Operation[] calldata operations) external payable;

/**
* @dev returns the address of the forwarder contract used to route batch operations of type
* OPERATION_TYPE_ERC2771_FORWARD_CALL.
* Needs to be set as _trusted forwarder_ by the call targets of such operations.
*/
// solhint-disable func-name-mixedcase
function getERC2771Forwarder() external view returns(address);

/**************************************************************************
* Function modifiers for access control and parameter validations
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ contract SuperfluidMock is Superfluid {
bool nonUpgradable,
bool appWhiteListingEnabled,
uint64 callbackGasLimit,
address dmzForwarder
address erc2771Forwarder
)
Superfluid(nonUpgradable, appWhiteListingEnabled, callbackGasLimit, dmzForwarder)
Superfluid(nonUpgradable, appWhiteListingEnabled, callbackGasLimit, erc2771Forwarder)
// solhint-disable-next-line no-empty-blocks
{
}
Expand Down
21 changes: 15 additions & 6 deletions packages/ethereum-contracts/contracts/superfluid/Superfluid.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import { SuperfluidUpgradeableBeacon } from "../upgradability/SuperfluidUpgradea
import { CallUtils } from "../libs/CallUtils.sol";
import { CallbackUtils } from "../libs/CallbackUtils.sol";
import { BaseRelayRecipient } from "../libs/BaseRelayRecipient.sol";
import { DMZForwarder } from "../utils/DMZForwarder.sol";
import { SimpleForwarder } from "../utils/SimpleForwarder.sol";
import { ERC2771Forwarder } from "../utils/ERC2771Forwarder.sol";

/**
* @dev The Superfluid host implementation.
Expand Down Expand Up @@ -54,7 +55,10 @@ contract Superfluid is

uint64 immutable public CALLBACK_GAS_LIMIT;

DMZForwarder immutable public DMZ_FORWARDER;
// simple forwarder contract used to relay arbitrary calls for batch operations
// Note: address will change with every contract upgrade
SimpleForwarder immutable public SIMPLE_FORWARDER;
ERC2771Forwarder immutable internal _ERC2771_FORWARDER;

/**
* @dev Maximum number of level of apps can be composed together
Expand Down Expand Up @@ -101,12 +105,13 @@ contract Superfluid is
bool nonUpgradable,
bool appWhiteListingEnabled,
uint64 callbackGasLimit,
address dmzForwarderAddress
address erc2771ForwarderAddress
) {
NON_UPGRADABLE_DEPLOYMENT = nonUpgradable;
APP_WHITE_LISTING_ENABLED = appWhiteListingEnabled;
CALLBACK_GAS_LIMIT = callbackGasLimit;
DMZ_FORWARDER = DMZForwarder(dmzForwarderAddress);
_ERC2771_FORWARDER = ERC2771Forwarder(erc2771ForwarderAddress);
SIMPLE_FORWARDER = new SimpleForwarder();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -888,15 +893,15 @@ contract Superfluid is
operations[i].data);
} else if (operationType == BatchOperation.OPERATION_TYPE_SIMPLE_FORWARD_CALL) {
(bool success, bytes memory returnData) =
DMZ_FORWARDER.forwardCall{value: address(this).balance}(
SIMPLE_FORWARDER.forwardCall{value: address(this).balance}(
operations[i].target,
operations[i].data);
if (!success) {
CallUtils.revertFromReturnedData(returnData);
}
} else if (operationType == BatchOperation.OPERATION_TYPE_ERC2771_FORWARD_CALL) {
(bool success, bytes memory returnData) =
DMZ_FORWARDER.forward2771Call{value: address(this).balance}(
_ERC2771_FORWARDER.forward2771Call{value: address(this).balance}(
operations[i].target,
msgSender,
operations[i].data);
Expand Down Expand Up @@ -949,6 +954,10 @@ contract Superfluid is
return "v1";
}

function getERC2771Forwarder() external view override returns(address) {
return address(_ERC2771_FORWARDER);
}

/**************************************************************************
* Internal
**************************************************************************/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,9 @@ pragma solidity ^0.8.23;
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

/**
* @title DMZForwarder
* @dev The purpose of this contract is to make arbitrary contract calls batchable
* alongside Superfluid specific batch operations.
* We route the calls through this dedicated contract in order to not have msg.sender set
* to the host contract, for security reasons.
* Forwarded calls can optionally use ERC-2771 to preserve the original msg.sender.
* If native tokens (msg.value) are provided, they are forwarded as well.
* @title Forwards calls preserving the original msg.sender according to ERC-2771
*/
contract DMZForwarder is Ownable {
/**
* @dev Forwards a call for which msg.sender doesn't matter
* @param target The target contract to call
* @param data The call data
*/
function forwardCall(address target, bytes memory data)
external payable
returns(bool success, bytes memory returnData)
{
// solhint-disable-next-line avoid-low-level-calls
(success, returnData) = target.call{value: msg.value}(data);
}

contract ERC2771Forwarder is Ownable {
/**
* @dev Forwards a call passing along the original msg.sender encoded as specified in ERC-2771.
* @param target The target contract to call
Expand Down
34 changes: 34 additions & 0 deletions packages/ethereum-contracts/contracts/utils/SimpleForwarder.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";

/**
* @title Forwards arbitrary calls
* @dev The purpose of this contract is to let accounts forward arbitrary calls,
* without themselves being the msg.sender from the perspective of the call target.
* This is necessary for security reasons if the calling account has privileged access anywhere.
*/
contract SimpleForwarder is Ownable {
/**
* @dev Forwards a call for which msg.sender doesn't matter
* @param target The target contract to call
* @param data The call data
* Note: restricted to `onlyOwner` in order to minimize attack surface
*/
function forwardCall(address target, bytes calldata data)
external payable onlyOwner
returns (bool success, bytes memory returnData)
{
// solhint-disable-next-line avoid-low-level-calls
(success, returnData) = target.call{value: msg.value}(data);
}

/**
* @dev Allows to withdraw native tokens (ETH) which got stuck in this contract.
* This could happen if a call fails, but the caller doesn't revert the tx.
*/
function withdrawLostNativeTokens(address payable receiver) external onlyOwner {
receiver.transfer(address(this).balance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity >=0.8.11;

import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SuperfluidFrameworkDeploymentSteps, TokenDeployerLibrary } from "./SuperfluidFrameworkDeploymentSteps.sol";
import { SuperfluidFrameworkDeploymentSteps, TokenDeployerLibrary } from "./SuperfluidFrameworkDeploymentSteps.t.sol";
import { ISuperTokenFactory } from "../superfluid/SuperTokenFactory.sol";
import { SuperToken } from "../superfluid/SuperToken.sol";
import { TestToken } from "./TestToken.sol";
Expand Down
Loading

0 comments on commit 05733de

Please sign in to comment.