-
Notifications
You must be signed in to change notification settings - Fork 107
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
base: bridge-next-gen
Are you sure you want to change the base?
Transact from sub to eth #1145
Conversation
Codecov ReportAttention: Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this 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.
contracts/src/utils/Call.sol
Outdated
/// @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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thoughts about this:
-
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. Thereturndata
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 -
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore returndata 0a8dc1e
There was a problem hiding this comment.
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
|
||
## Explanation | ||
|
||
We use penpal for the integration, basically it works as follows: |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
For step 2 the sovereign of Penpal only pays(DOT) for the delivery(local fee) portion, there is no refund in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summarize it in bd88ed8
1113521
to
b89cc6c
Compare
contracts/src/Gateway.sol
Outdated
if (!success) { | ||
revert AgentTransactCallFailed(); | ||
} | ||
emit TransactExecuted(params.agentID, params.target, params.payload); |
There was a problem hiding this comment.
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
emit TransactExecuted(params.agentID, params.target, params.payload); | |
emit TransactExecuted(params.agentID, params.target, keccak256(params.payload)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contracts/src/Params.sol
Outdated
/// @dev Payload of the call | ||
bytes payload; | ||
/// @dev Max gas cost of the call | ||
uint64 dynamicGas; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
event TransactExecuted(bytes32 indexed agentID, address indexed target, bytes payload); | |
event Transacted(bytes32 indexed agentID, address indexed target, bytes32 payloadHash); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
contracts/src/utils/Call.sol
Outdated
/// @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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3dcd8ed
to
fe513c7
Compare
Resolves: SNO-586,SNO-866,SNO-696
Requires: Snowfork/polkadot-sdk#116