Skip to content

Conversation

@gfournieriExec
Copy link
Contributor

No description provided.

Copilot AI review requested due to automatic review settings November 6, 2025 12:10
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements atomic approve+deposit+match functionality for the IexecEscrow contract, allowing users to approve tokens, deposit them, and match orders in a single transaction through the receiveApproval callback mechanism. This provides a better UX by reducing gas costs and transaction complexity.

Key Changes:

  • Extended receiveApproval to support optional order matching via encoded calldata
  • Added comprehensive test coverage for the new atomic operation flow
  • Migrated several contracts from Solidity 0.6 to 0.8 (SafeMath removal)

Reviewed Changes

Copilot reviewed 20 out of 21 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
utils/odb-tools.ts Added encodeOrders function to ABI-encode orders for callback data
test/byContract/IexecEscrow/IexecEscrowToken.receiveApproval.test.ts Comprehensive test suite for atomic approve+deposit+match flow
contracts/facets/IexecEscrowTokenFacet.sol Enhanced receiveApproval with order matching and migrated to Solidity 0.8
contracts/interfaces/IexecEscrowToken.sol Added ApprovalReceivedAndMatched event definition
contracts/interfaces/IexecERC20Common.sol Moved Transfer and Approval event definitions from IexecERC20
contracts/interfaces/IexecERC20.sol Removed duplicate event definitions
contracts/facets/IexecERC20Core.sol Migrated to Solidity 0.8, replaced SafeMath with native operators
contracts/facets/IexecERC20Facet.sol Migrated to Solidity 0.8, added underflow checks
contracts/facets/IexecEscrowNativeFacet.sol Migrated to Solidity 0.8, replaced SafeMath with native operators
contracts/facets/FacetBase.v8.sol Added onlyOwner modifier and owner() helper
package-lock.json Removed duplicate hardhat dependency entry
abis/**/*.json Updated ABI files to reflect event and interface changes

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@gfournieriExec gfournieriExec changed the base branch from main to chore/solidity-v8 November 6, 2025 14:22
Copilot AI review requested due to automatic review settings November 6, 2025 14:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@gfournieriExec gfournieriExec changed the base branch from chore/solidity-v8 to fix/format-sc November 6, 2025 14:58
Copilot AI review requested due to automatic review settings November 6, 2025 15:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// Token Spender (endpoint for approveAndCallback calls to the proxy)
/***************************************************************************
* Token Spender: Atomic Approve+Deposit+Match *
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* Token Spender: Atomic Approve+Deposit+Match *
* Token Spender: Atomic Deposit+Match if used with RLC.approveAndCall *

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
Member

Choose a reason for hiding this comment

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

Up here. The comment is not correct we only have 2 of them, deposit and match.


/**
* @notice Receives approval and optionally matches orders in one transaction
* @dev This is the magic function that enables approve+deposit+match atomicity
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* @dev This is the magic function that enables approve+deposit+match atomicity

Copy link
Contributor Author

Choose a reason for hiding this comment

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

* bytes memory data = abi.encode(appOrder, datasetOrder, workerpoolOrder, requestOrder);
*
* // One transaction does it all
* RLC.approveAndCall(iexecProxy, dealCost, data);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* RLC.approveAndCall(iexecProxy, dealCost, data);
* RLC(token).approveAndCall(iexecProxy, dealCost, data);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if (data.length > 0) {
dealId = _matchOrdersAfterDeposit(sender, data);
}
emit ApprovalReceivedAndMatched(sender, amount, dealId);
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is needed because we already have enough logs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

_deposit(sender, amount);
_mint(sender, amount);
bytes32 dealId = bytes32(0);
if (data.length > 0) {
Copy link
Member

Choose a reason for hiding this comment

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

We have two choices here:

  1. data = encoded orders: the simpler option but limited for future updates
  2. data = matchOrders selector + encoded orders: this version seems a bit more complicated but it allows for easier future evolutions. We can encode the hole call and check the selector, if it is matchOrders than do the call, if not revert. This way when we want to add a new operation the SDK needs just to encode the new call and we'll need to allow it. The behavior does not change from only encoding call arguments to encoding the full call.
if (data.length == 0) {
    return true;
}
if (getSelector(data) == matchOrders.selector) {
    matchOrders
    return true;
}
revert;

* @param data ABI-encoded orders
* @return dealId The deal ID of the matched deal
*/
function _matchOrdersAfterDeposit(
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
function _matchOrdersAfterDeposit(
function _decodeDataAndMatchOrders(

Copy link
Contributor Author

Choose a reason for hiding this comment

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


// Call matchOrders on the IexecPoco1 facet through the diamond
// Using delegatecall pattern via address(this)
(bool success, bytes memory result) = address(this).call(
Copy link
Member

Choose a reason for hiding this comment

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

We need to check which is safer:

  1. call: msg.sender is the PoCo
  2. delegatecall: msg.sender is the RLC
    Option 2 is clearly safer but we need to check if it's a problem for the matching.

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 requestOrder Request order struct
* @returns ABI-encoded orders
*/
export function encodeOrders(
Copy link
Member

Choose a reason for hiding this comment

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

We need to encode orders programatically so that we have an example of the client's code.

Copy link
Contributor

Choose a reason for hiding this comment

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

i don't understand this com

@codecov
Copy link

codecov bot commented Nov 6, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.37%. Comparing base (a8d8779) to head (5fee6ac).

Additional details and impacted files
@@                  Coverage Diff                  @@
##           chore/solidity-v8     #316      +/-   ##
=====================================================
+ Coverage              96.32%   96.37%   +0.04%     
=====================================================
  Files                     34       34              
  Lines                   1117     1130      +13     
  Branches                 209      227      +18     
=====================================================
+ Hits                    1076     1089      +13     
  Misses                    41       41              

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copilot AI review requested due to automatic review settings November 6, 2025 17:33
@zguesmi zguesmi changed the title Feat/deposit match order via receive approval feat: Enable deposit and match orders in a single tx Nov 6, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings November 7, 2025 09:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +118 to +120
bytes32 dealId = bytes32(0);
if (data.length > 0) {
dealId = _decodeDataAndMatchOrders(sender, data);
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

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

The variable dealId is initialized to bytes32(0) but is never used after line 120. Consider removing this variable declaration entirely since the return value from _decodeDataAndMatchOrders is not used anywhere.

Suggested change
bytes32 dealId = bytes32(0);
if (data.length > 0) {
dealId = _decodeDataAndMatchOrders(sender, data);
if (data.length > 0) {
_decodeDataAndMatchOrders(sender, data);

Copilot uses AI. Check for mistakes.
Base automatically changed from fix/format-sc to chore/solidity-v8 November 7, 2025 09:47
@gfournieriExec gfournieriExec marked this pull request as ready for review November 7, 2025 09:51
Copilot AI review requested due to automatic review settings November 7, 2025 09:51
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings November 7, 2025 13:48
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +446 to +453

async function signAndPrepareOrders(orders: IexecOrders): Promise<void> {
await signOrders(iexecWrapper.getDomain(), orders, ordersActors);
}

function encodeOrdersForCallback(orders: IexecOrders): string {
return encodeOrders(orders.app, orders.dataset, orders.workerpool, orders.requester);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Are those wrappers really necessary? We’re replacing one line with three.


// Token Spender (endpoint for approveAndCallback calls to the proxy)
/***************************************************************************
* Token Spender: Atomic Approve+Deposit+Match *
Copy link
Member

Choose a reason for hiding this comment

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

Up here. The comment is not correct we only have 2 of them, deposit and match.

if (requestorder.requester != sender) revert("caller-must-be-requester");

// Call matchOrders on the IexecPoco1 facet through the diamond
// Using delegatecall for safety: preserves msg.sender context
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Using delegatecall for safety: preserves msg.sender context
// Using delegatecall for safety: preserves msg.sender context (RLC address in this case)

Comment on lines +185 to +188
// Decode the dealId from successful call
dealId = abi.decode(result, (bytes32));

return dealId;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Decode the dealId from successful call
dealId = abi.decode(result, (bytes32));
return dealId;

Comment on lines +185 to +188
// Decode the dealId from successful call
dealId = abi.decode(result, (bytes32));

return dealId;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// Decode the dealId from successful call
dealId = abi.decode(result, (bytes32));
return dealId;

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.

3 participants