Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ETHEREUM-CONTRACTS] | #1038 | Allow regular contracts to be the target of callAppAction #1238

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/ethereum-contracts/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

- `upgradeTo` logic changed to revert if `data` is not empty and `to` is a contract and is not a registered ERC777 recipient
- `MAX_APP_CALLBACK_LEVEL` is public again
- `callAppAction` and `callAppActionWithContext` can be called where `app` is a non-super app smart contract as long as it satisfies two requirements:
1. The function you want to call via `callAppAction` must take bytes (the passed context from the host) as the last parameter.
2. You must return the "correct" context bytes from the contract in the function, that is, untouched.

### [v1.4.3] - 2022-10-27
### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,10 @@ interface ISuperfluid {
error APP_RULE(uint256 _code); // 0xa85ba64f

error HOST_INVALID_OR_EXPIRED_SUPER_APP_REGISTRATION_KEY(); // 0x19ab84d1
error HOST_NOT_A_SUPER_APP(); // 0x163cbe43
error HOST_NO_APP_REGISTRATION_PERMISSIONS(); // 0x5b93ebf0
error HOST_RECEIVER_IS_NOT_SUPER_APP(); // 0x96aa315e
error HOST_SENDER_IS_NOT_SUPER_APP(); // 0xbacfdc40
error HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL(); // 0x44725270
error HOST_SUPER_APP_IS_JAILED(); // 0x02384b64
error HOST_SUPER_APP_ALREADY_REGISTERED(); // 0x01b0a935
error HOST_UNAUTHORIZED_SUPER_APP_FACTORY(); // 0x289533c5

Expand Down Expand Up @@ -462,7 +460,6 @@ interface ISuperfluid {
)
external
//cleanCtx
//isAppActive(app)
//isValidAppAction(callData)
returns(bytes memory returnedData);

Expand Down Expand Up @@ -549,7 +546,6 @@ interface ISuperfluid {
)
external
// requireValidCtx(ctx)
// isAppActive(app)
returns (bytes memory newCtx);

function decodeCtx(bytes memory ctx)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: AGPLv3
pragma solidity 0.8.16;

import {ISuperApp, ISuperfluid} from "../superfluid/Superfluid.sol";

/// @title Non SuperApp Contract Mock
/// @author Superfluid
/// @notice This contract is used to test call app action against a non super app contract
/// @dev It is important to note that callAppAction and callAppActionWithContext is allowed to be called
/// by any contract. But, the `function` you want to invokeCallAppAction on must satisfy two requirements:
/// 1. The `function` you want to call via callAppAction must take context bytes as the last parameter.
/// 2. You must return the "correct" context bytes from the contract in the `function`, that is, untouched.
contract NonSuperAppContractMock {
ISuperfluid public superfluid;
constructor(ISuperfluid _superfluid) {
superfluid = _superfluid;
}

event Log(uint256 amount);

/// @notice An example of a function that does not satisfy the requirements for callAppAction
/// @dev This does not satsify requirements 1 or 2
/// @param _amount arbitrary amount
function invalidCallAppActionFunction(uint256 _amount) external {
emit Log(_amount);
}

/// @notice An example of a sneaky function that does not satisfy the requirements for callAppAction
/// @dev This satisfies requirement 1 but not 2
/// @param _amount arbitrary amount
/// @return newCtx the context bytes
function sneakyCallAppActionFunction(
uint256 _amount,
bytes calldata //_ctx
) external returns (bytes memory newCtx) {
emit Log(_amount);
}


/// @notice An example of a function that satisfies the requirements for callAppAction
/// @dev This satisfies requirements 1 and 2
/// @param _amount arbitrary amount
/// @param _ctx correct context bytes
/// @return newCtx the context bytes
function validCallAppActionFunction(
uint256 _amount,
bytes calldata _ctx
) external returns (bytes memory newCtx) {
emit Log(_amount);
newCtx = _ctx;
}
}
25 changes: 25 additions & 0 deletions packages/ethereum-contracts/contracts/mocks/SuperAppMocks.sol
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,31 @@ contract SuperAppMock is ISuperApp {
abi.encode(42));
}

function validCallAppActionOnNonSuperAppWithCtx(
address _nonSuperAppContract,
bytes calldata callData,
bytes calldata ctx
) external requireValidCtx(ctx) returns (bytes memory newCtx) {
newCtx = _host.callAppActionWithContext(
ISuperApp(_nonSuperAppContract),
callData,
ctx
);
}

function invalidCallAppActionOnNonSuperAppWithCtx(
address _nonSuperAppContract,
bytes calldata callData,
bytes calldata ctx
) external requireValidCtx(ctx) returns (bytes memory newCtx) {
newCtx = _host.callAppActionWithContext(
ISuperApp(_nonSuperAppContract),
callData,
// we tamper with the original ctx passed by host.callAppAction to make it invalid
"0x"
);
}

function actionCallBadAction(bytes calldata ctx)
external
requireValidCtx(ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,6 @@ contract Superfluid is
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's also ban calling this (the host contract itself) as target.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also remove the ISuperApp type, and call app e.g. "target"

internal
cleanCtx
isAppActive(app)
isValidAppAction(callData)
returns(bytes memory returnedData)
{
Expand Down Expand Up @@ -731,7 +730,6 @@ contract Superfluid is
)
external override
requireValidCtx(ctx)
isAppActive(app)
isValidAppAction(callData)
returns(bytes memory newCtx)
{
Expand Down Expand Up @@ -1098,13 +1096,6 @@ contract Superfluid is
_;
}

modifier isAppActive(ISuperApp app) {
uint256 configWord = _appManifests[app].configWord;
if (configWord == 0) revert HOST_NOT_A_SUPER_APP();
if (SuperAppDefinitions.isAppJailed(configWord)) revert HOST_SUPER_APP_IS_JAILED();
_;
}

modifier isValidAppAction(bytes memory callData) {
bytes4 actionSelector = CallUtils.parseSelector(callData);
if (actionSelector == ISuperApp.beforeAgreementCreated.selector ||
Expand Down
4 changes: 2 additions & 2 deletions packages/ethereum-contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@
"readline": "1.3.0",
"solhint": "3.3.7",
"solidity-coverage": "0.8.2",
"solidity-docgen": "^0.6.0-beta.30",
"solidity-docgen": "^0.6.0-beta.32",
"truffle-flattener": "^1.6.0",
"truffle-plugin-verify": "0.6.0"
"truffle-plugin-verify": "0.6.1"
}
}
Loading