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

Transact from sub to eth #1145

Open
wants to merge 25 commits into
base: bridge-next-gen
Choose a base branch
from
Open

Conversation

yrong
Copy link
Contributor

@yrong yrong commented Feb 20, 2024

Copy link

codecov bot commented Feb 20, 2024

Codecov Report

Attention: Patch coverage is 88.00000% with 3 lines in your changes are missing coverage. Please review.

❗ No coverage uploaded for pull request base (bridge-next-gen@7f41605). Click here to learn what that means.

❗ Current head 8ceb5ee differs from pull request most recent head b7e85ca. Consider uploading reports for the commit b7e85ca to get more accurate results

Files Patch % Lines
contracts/src/FundAgent.sol 0.00% 3 Missing ⚠️
Additional details and impacted files
@@                Coverage Diff                 @@
##             bridge-next-gen    #1145   +/-   ##
==================================================
  Coverage                   ?   79.72%           
==================================================
  Files                      ?       14           
  Lines                      ?      429           
  Branches                   ?       76           
==================================================
  Hits                       ?      342           
  Misses                     ?       71           
  Partials                   ?       16           
Flag Coverage Δ
solidity 79.72% <88.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@yrong yrong marked this pull request as ready for review February 21, 2024 15:07
@yrong yrong requested review from vgeddes, alistair-singh and claravanstaden and removed request for vgeddes and alistair-singh February 22, 2024 07:20
Copy link
Contributor

@alistair-singh alistair-singh left a comment

Choose a reason for hiding this comment

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

Looks good! Just one comment tests.

Comment on lines 26 to 28
/// @notice Use when you _really_ really _really_ don't trust the called
/// contract. This prevents the called contract from causing reversion of
/// the caller in as many ways as we can.
Copy link
Contributor

Choose a reason for hiding this comment

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

We should understand how using zexcessivelySafeCall` can still fail? And potentially have tests for at least one case to make sure we don't poisen pill the inbound queue.

Copy link
Contributor Author

@yrong yrong Feb 27, 2024

Choose a reason for hiding this comment

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

Yeah, an unsafe call could be dangerous so we need to be very careful here. Except that I would also like to introduce white-list access control, something like the SafeCallFilter but on Ethereum side.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

@vgeddes vgeddes Mar 4, 2024

Choose a reason for hiding this comment

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

My thoughts about this:

  1. I think excessivelySafeCall (used by Nomad) is too complicated for our needs. When issuing a call, we are only interested in whether the call succeeded or not. The returndata we can ignore. For this reason, I prefer that we use this safe call solution: https://github.com/ethereum-optimism/optimism/blob/b36eb5515cc2a34a15383b2eee488dbac83d6caf/packages/contracts-bedrock/src/libraries/SafeCall.sol#L12

  2. I am optimistic we've accounted for all the ways a contract call can be unsafe. This includes guards against re-entrancy (nonce check), gas limits, and returnbomb attacks. Therefore I don't see a reason to include a safe call filter. If we think a call can still be unsafe, we need to understand why. For now I would just remove the safe call filter.

Copy link
Collaborator

@musnit musnit Mar 4, 2024

Choose a reason for hiding this comment

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

@yrong How does SafeCallFilter work? Will we have to restrict allowing transact to only explicitly specified contracts and/or functions? This won't work - we 100% need permissionless support for anyone to integrate transacting with any contract and any function without permission.

And yeah agree with @vgeddes on just ignoring all returndata

Copy link
Contributor Author

@yrong yrong Mar 5, 2024

Choose a reason for hiding this comment

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

How does SafeCallFilter work? Will we have to restrict allowing transact to only explicitly specified contracts and/or functions?

It's not by us or requires governance from the relaychain, but instead from the Parachain sovereign through xcm(i.e. require another call added in our system pallet), they can increase the whitelist step by step entirely under their control.

In this way, we can release the transact support without introducing potential risk.

Copy link
Contributor Author

@yrong yrong Apr 15, 2024

Choose a reason for hiding this comment

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

Ignore returndata 0a8dc1e

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allow arbitray transact without any black(white)-list 606e867

@yrong yrong marked this pull request as draft March 14, 2024 15:29
@yrong yrong mentioned this pull request Mar 29, 2024
@yrong yrong changed the base branch from main to bridge-next-gen April 11, 2024 06:11
@yrong yrong marked this pull request as ready for review April 15, 2024 02:36
contracts/src/DeployScript.sol Outdated Show resolved Hide resolved

## Explanation

We use penpal for the integration, basically it works as follows:
Copy link
Contributor

Choose a reason for hiding this comment

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

Fee flow:

  • User represents a user who kicks off an extrinsic on the parachain.
  • Parachain represents the source parachain, its sovereign or its agent depending on context.
Sequence Where Who What
1 Parachain User pays(DOT, Native) to node to execute custom extrinsic; pays (DOT) to Treasury for delivery as part of custom extrinsic.
2 Bridge Hub Parachain pays(DOT) to Treasury Account for delivery(local fee), pays(DOT) to Parachain sovereign for delivery(remote fee), essentially a refund. Remote fee converted to ETH here.
3 Gateway Relayer pays(ETH) to validate and execute message.
4 Gateway Parachain Agent pays(ETH) to relayer for delivery(reward+refund) and execution.

Does this balance? No, Parachain agent pays for delivery and execution on the Ethereum side. User only pays for calling the extrinsic and delivery on the source Parachain. Because the custom extrinsic essentially allows the user to impersonate the parachain on ethereum side it becomes the Parachains job to charge appropriately for both delivery and execution. This doesn't mean there is something wrong with the implementation, just that this needs to be communication to creator of the custom extrinsic.

Copy link
Contributor Author

@yrong yrong Apr 22, 2024

Choose a reason for hiding this comment

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

For step 1 user pays(DOT) to Treasury for both the delivery cost on BH and execution cost on Ethereum.

https://github.com/Snowfork/polkadot-sdk/blob/569d638d429944fc8d4e2d7db3b653d565879f86/cumulus/parachains/runtimes/testing/penpal/src/pallets/transact_helper.rs#L99-L100

For step 2 the sovereign of Penpal only pays(DOT) for the delivery(local fee) portion, there is no refund in this case.

https://github.com/Snowfork/polkadot-sdk/blob/569d638d429944fc8d4e2d7db3b653d565879f86/bridges/snowbridge/primitives/router/src/outbound/mod.rs#L119-L125

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Summarize it in bd88ed8

contracts/src/Gateway.sol Outdated Show resolved Hide resolved
smoketest/tests/transact_from_penpal_to_ethereum.rs Outdated Show resolved Hide resolved
@yrong yrong force-pushed the ron/transact-from-sub-to-eth branch from 1113521 to b89cc6c Compare April 24, 2024 12:56
if (!success) {
revert AgentTransactCallFailed();
}
emit TransactExecuted(params.agentID, params.target, params.payload);
Copy link
Collaborator

Choose a reason for hiding this comment

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

params.payload could be very large, cheaper to hash it when emitting event

Suggested change
emit TransactExecuted(params.agentID, params.target, params.payload);
emit TransactExecuted(params.agentID, params.target, keccak256(params.payload));

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/// @dev Payload of the call
bytes payload;
/// @dev Max gas cost of the call
uint64 dynamicGas;
Copy link
Collaborator

Choose a reason for hiding this comment

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

The message packet already has a maxDispatchGas, which is the upper limit a transact can consume. So I am not sure what role this dynamicGas plays.

The gas estimator on BridgeHub should add a buffer to maxDispatchGas to cover the cost of dispatching via the agent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it's the same thing. Just rename it for less confusion.
27c14e9

@@ -35,6 +35,8 @@ interface IGateway {
// Emitted when funds are withdrawn from an agent
event AgentFundsWithdrawn(bytes32 indexed agentID, address indexed recipient, uint256 amount);

event TransactExecuted(bytes32 indexed agentID, address indexed target, bytes payload);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
event TransactExecuted(bytes32 indexed agentID, address indexed target, bytes payload);
event Transacted(bytes32 indexed agentID, address indexed target, bytes32 payloadHash);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/// @param _calldata The data to send to the remote contract
/// @return success and returndata, as `.call()`. Returndata is capped to
/// `_maxCopy` bytes.
function excessivelySafeCall(address _target, uint256 _gas, uint256 _value, uint16 _maxCopy, bytes memory _calldata)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We're no longer using this, can we remove it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@yrong yrong force-pushed the ron/transact-from-sub-to-eth branch from 3dcd8ed to fe513c7 Compare May 2, 2024 03:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants