From aea6131a7fc1e32b2321cec9d6fad8810611f0b7 Mon Sep 17 00:00:00 2001 From: gfournieriExec Date: Fri, 25 Jul 2025 17:13:27 +0200 Subject: [PATCH 1/6] feat: Migrate from delegateSmart contract to facet naming --- contracts/modules/DelegateBase.sol | 3 +- contracts/modules/DelegateBase.v8.sol | 5 +- contracts/modules/FacetBase.sol | 26 ++ contracts/modules/FacetBase.v8.sol | 31 +++ .../IexecAccessorsABILegacyDelegate.sol | 159 ------------- .../delegates/IexecAccessorsDelegate.sol | 223 ------------------ .../modules/delegates/IexecERC20Delegate.sol | 74 ------ .../delegates/IexecEscrowNativeDelegate.sol | 112 --------- .../delegates/IexecEscrowTokenDelegate.sol | 120 ---------- .../IexecEscrowTokenSwapDelegate.sol | 163 ------------- .../delegates/IexecMaintenanceDelegate.sol | 92 -------- .../modules/delegates/SignatureVerifier.sol | 177 -------------- .../facets/IexecAccessorsABILegacyFacet.sol | 137 +++++++++++ .../modules/facets/IexecAccessorsFacet.sol | 166 +++++++++++++ .../IexecCategoryManagerFacet.sol} | 42 ++-- .../{delegates => facets}/IexecERC20Core.sol | 4 +- contracts/modules/facets/IexecERC20Facet.sol | 81 +++++++ .../{delegates => facets}/IexecEscrow.v8.sol | 4 +- .../modules/facets/IexecEscrowNativeFacet.sol | 92 ++++++++ .../modules/facets/IexecEscrowTokenFacet.sol | 103 ++++++++ .../facets/IexecEscrowTokenSwapFacet.sol | 222 +++++++++++++++++ .../IexecMaintenanceExtraFacet.sol} | 25 +- .../modules/facets/IexecMaintenanceFacet.sol | 79 +++++++ .../IexecOrderManagementFacet.sol} | 4 +- .../IexecPoco1Facet.sol} | 10 +- .../IexecPoco2Facet.sol} | 4 +- .../IexecPocoAccessorsFacet.sol} | 10 +- .../IexecPocoBoostAccessorsFacet.sol} | 4 +- .../IexecPocoBoostFacet.sol} | 10 +- .../IexecPocoCommonFacet.sol} | 4 +- .../IexecRelayFacet.sol} | 28 ++- .../modules/facets/SignatureVerifier.sol | 172 ++++++++++++++ .../SignatureVerifier.v8.sol | 4 +- .../tools/testing/IexecEscrowTestContract.sol | 2 +- .../IexecPocoBoostCompositeDelegate.sol | 14 +- .../testing/IexecPocoBoostCompositeFacet.sol | 17 ++ contracts/tools/testing/slither/Slither.sol | 8 +- .../tools/testing/slither/SlitherBoost.sol | 6 +- hardhat.config.ts | 8 +- 39 files changed, 1223 insertions(+), 1222 deletions(-) create mode 100644 contracts/modules/FacetBase.sol create mode 100644 contracts/modules/FacetBase.v8.sol delete mode 100644 contracts/modules/delegates/IexecAccessorsABILegacyDelegate.sol delete mode 100644 contracts/modules/delegates/IexecAccessorsDelegate.sol delete mode 100644 contracts/modules/delegates/IexecERC20Delegate.sol delete mode 100644 contracts/modules/delegates/IexecEscrowNativeDelegate.sol delete mode 100644 contracts/modules/delegates/IexecEscrowTokenDelegate.sol delete mode 100644 contracts/modules/delegates/IexecEscrowTokenSwapDelegate.sol delete mode 100644 contracts/modules/delegates/IexecMaintenanceDelegate.sol delete mode 100644 contracts/modules/delegates/SignatureVerifier.sol create mode 100644 contracts/modules/facets/IexecAccessorsABILegacyFacet.sol create mode 100644 contracts/modules/facets/IexecAccessorsFacet.sol rename contracts/modules/{delegates/IexecCategoryManagerDelegate.sol => facets/IexecCategoryManagerFacet.sol} (71%) rename contracts/modules/{delegates => facets}/IexecERC20Core.sol (96%) create mode 100644 contracts/modules/facets/IexecERC20Facet.sol rename contracts/modules/{delegates => facets}/IexecEscrow.v8.sol (97%) create mode 100644 contracts/modules/facets/IexecEscrowNativeFacet.sol create mode 100644 contracts/modules/facets/IexecEscrowTokenFacet.sol create mode 100644 contracts/modules/facets/IexecEscrowTokenSwapFacet.sol rename contracts/modules/{delegates/IexecMaintenanceExtraDelegate.sol => facets/IexecMaintenanceExtraFacet.sol} (73%) create mode 100644 contracts/modules/facets/IexecMaintenanceFacet.sol rename contracts/modules/{delegates/IexecOrderManagementDelegate.sol => facets/IexecOrderManagementFacet.sol} (97%) rename contracts/modules/{delegates/IexecPoco1Delegate.sol => facets/IexecPoco1Facet.sol} (98%) rename contracts/modules/{delegates/IexecPoco2Delegate.sol => facets/IexecPoco2Facet.sol} (99%) rename contracts/modules/{delegates/IexecPocoAccessorsDelegate.sol => facets/IexecPocoAccessorsFacet.sol} (92%) rename contracts/modules/{delegates/IexecPocoBoostAccessorsDelegate.sol => facets/IexecPocoBoostAccessorsFacet.sol} (83%) rename contracts/modules/{delegates/IexecPocoBoostDelegate.sol => facets/IexecPocoBoostFacet.sol} (99%) rename contracts/modules/{delegates/IexecPocoCommonDelegate.sol => facets/IexecPocoCommonFacet.sol} (95%) rename contracts/modules/{delegates/IexecRelayDelegate.sol => facets/IexecRelayFacet.sol} (63%) create mode 100644 contracts/modules/facets/SignatureVerifier.sol rename contracts/modules/{delegates => facets}/SignatureVerifier.v8.sol (98%) create mode 100644 contracts/tools/testing/IexecPocoBoostCompositeFacet.sol diff --git a/contracts/modules/DelegateBase.sol b/contracts/modules/DelegateBase.sol index 435b5d0ae..56e3c7535 100644 --- a/contracts/modules/DelegateBase.sol +++ b/contracts/modules/DelegateBase.sol @@ -9,9 +9,8 @@ import "./interfaces/IOwnable.sol"; // Functions that were declared in ERC1538Store are re-declared here. // TODO clean this (use LibDiamond) // - All calls to `owner()` should use `LibDiamond.contractOwner()`. -// TODO rename this contract to `FacetBase`. -abstract contract DelegateBase is Store { +abstract contract FacetBase is Store { modifier onlyOwner() { require(_msgSender() == owner(), "Ownable: caller is not the owner"); _; diff --git a/contracts/modules/DelegateBase.v8.sol b/contracts/modules/DelegateBase.v8.sol index e2f44e8d8..23b43b5d9 100644 --- a/contracts/modules/DelegateBase.v8.sol +++ b/contracts/modules/DelegateBase.v8.sol @@ -9,13 +9,12 @@ import {Store} from "../Store.v8.sol"; // Functions that were declared in ERC1538Store are re-declared here. // TODO clean this (use LibDiamond) // - All calls to `owner()` should use `LibDiamond.contractOwner()`. -// TODO rename this contract to `FacetBase`. /** - * @title Base contract of all Delegate contracts. + * @title Base contract of all Facet contracts. * @dev Every module must inherit from this contract. */ -abstract contract DelegateBase is Store { +abstract contract FacetBase is Store { modifier onlyOwner() { require(_msgSender() == owner(), "Ownable: caller is not the owner"); _; diff --git a/contracts/modules/FacetBase.sol b/contracts/modules/FacetBase.sol new file mode 100644 index 000000000..56e3c7535 --- /dev/null +++ b/contracts/modules/FacetBase.sol @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.6.0; + +import "../Store.sol"; +import "./interfaces/IOwnable.sol"; + +// Functions that were declared in ERC1538Store are re-declared here. +// TODO clean this (use LibDiamond) +// - All calls to `owner()` should use `LibDiamond.contractOwner()`. + +abstract contract FacetBase is Store { + modifier onlyOwner() { + require(_msgSender() == owner(), "Ownable: caller is not the owner"); + _; + } + + function owner() public view returns (address) { + return IOwnable(address(this)).owner(); + } + + function _msgSender() internal view returns (address) { + return msg.sender; + } +} diff --git a/contracts/modules/FacetBase.v8.sol b/contracts/modules/FacetBase.v8.sol new file mode 100644 index 000000000..23b43b5d9 --- /dev/null +++ b/contracts/modules/FacetBase.v8.sol @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2023 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.8.0; + +import {IERC5313} from "@openzeppelin/contracts-v5/interfaces/IERC5313.sol"; +import {Store} from "../Store.v8.sol"; + +// Functions that were declared in ERC1538Store are re-declared here. +// TODO clean this (use LibDiamond) +// - All calls to `owner()` should use `LibDiamond.contractOwner()`. + +/** + * @title Base contract of all Facet contracts. + * @dev Every module must inherit from this contract. + */ +abstract contract FacetBase is Store { + modifier onlyOwner() { + require(_msgSender() == owner(), "Ownable: caller is not the owner"); + _; + } + + function owner() public view returns (address) { + // Make an external call to delegatecall the OwnershipFacet. + return IERC5313(address(this)).owner(); + } + + function _msgSender() internal view returns (address) { + return msg.sender; + } +} diff --git a/contracts/modules/delegates/IexecAccessorsABILegacyDelegate.sol b/contracts/modules/delegates/IexecAccessorsABILegacyDelegate.sol deleted file mode 100644 index 17aaf11ac..000000000 --- a/contracts/modules/delegates/IexecAccessorsABILegacyDelegate.sol +++ /dev/null @@ -1,159 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -/****************************************************************************** - * Copyright 2020 IEXEC BLOCKCHAIN TECH * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - ******************************************************************************/ - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "../DelegateBase.sol"; -import "../interfaces/IexecAccessorsABILegacy.sol"; - - -contract IexecAccessorsABILegacyDelegate is IexecAccessorsABILegacy, DelegateBase -{ - function viewDealABILegacy_pt1(bytes32 _id) - external view override returns - ( address - , address - , uint256 - , address - , address - , uint256 - , address - , address - , uint256 - ) - { - IexecLibCore_v5.Deal memory deal = m_deals[_id]; - return ( - deal.app.pointer, - deal.app.owner, - deal.app.price, - deal.dataset.pointer, - deal.dataset.owner, - deal.dataset.price, - deal.workerpool.pointer, - deal.workerpool.owner, - deal.workerpool.price - ); - } - - function viewDealABILegacy_pt2(bytes32 _id) - external view override returns - ( uint256 - , bytes32 - , address - , address - , address - , string memory - ) - { - IexecLibCore_v5.Deal memory deal = m_deals[_id]; - return ( - deal.trust, - deal.tag, - deal.requester, - deal.beneficiary, - deal.callback, - deal.params - ); - } - - function viewConfigABILegacy(bytes32 _id) - external view override returns - ( uint256 - , uint256 - , uint256 - , uint256 - , uint256 - , uint256 - ) - { - IexecLibCore_v5.Deal memory deal = m_deals[_id]; - return ( - deal.category, - deal.startTime, - deal.botFirst, - deal.botSize, - deal.workerStake, - deal.schedulerRewardRatio - ); - } - - function viewAccountABILegacy(address account) - external view override returns (uint256, uint256) - { - return ( m_balances[account], m_frozens[account] ); - } - - function viewTaskABILegacy(bytes32 _taskid) - external view override returns - ( IexecLibCore_v5.TaskStatusEnum - , bytes32 - , uint256 - , uint256 - , uint256 - , uint256 - , uint256 - , bytes32 - , uint256 - , uint256 - , address[] memory - , bytes memory - ) - { - IexecLibCore_v5.Task memory task = m_tasks[_taskid]; - return ( - task.status, - task.dealid, - task.idx, - task.timeref, - task.contributionDeadline, - task.revealDeadline, - task.finalDeadline, - task.consensusValue, - task.revealCounter, - task.winnerCounter, - task.contributors, - task.results - ); - } - - function viewContributionABILegacy(bytes32 _taskid, address _worker) - external view override returns - ( IexecLibCore_v5.ContributionStatusEnum - , bytes32 - , bytes32 - , address - ) - { - IexecLibCore_v5.Contribution memory contribution = m_contributions[_taskid][_worker]; - return ( - contribution.status, - contribution.resultHash, - contribution.resultSeal, - contribution.enclaveChallenge - ); - } - - function viewCategoryABILegacy(uint256 _catid) - external view override returns (string memory, string memory, uint256) - { - IexecLibCore_v5.Category memory category = m_categories[_catid]; - return ( category.name, category.description, category.workClockTimeRef ); - } -} diff --git a/contracts/modules/delegates/IexecAccessorsDelegate.sol b/contracts/modules/delegates/IexecAccessorsDelegate.sol deleted file mode 100644 index 35dce1b66..000000000 --- a/contracts/modules/delegates/IexecAccessorsDelegate.sol +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -/****************************************************************************** - * Copyright 2020 IEXEC BLOCKCHAIN TECH * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - ******************************************************************************/ - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "../DelegateBase.sol"; -import "../interfaces/IexecAccessors.sol"; - - -contract IexecAccessorsDelegate is IexecAccessors, DelegateBase -{ - - function name() - external view override returns (string memory) - { - return m_name; - } - - function symbol() - external view override returns (string memory) - { - return m_symbol; - } - - function decimals() - external view override returns (uint8) - { - return m_decimals; - } - - function totalSupply() - external view override returns (uint256) - { - return m_totalSupply; - } - - function balanceOf(address account) - external view override returns (uint256) - { - return m_balances[account]; - } - - function frozenOf(address account) - external view override returns (uint256) - { - return m_frozens[account]; - } - - function allowance(address account, address spender) - external view override returns (uint256) - { - return m_allowances[account][spender]; - } - - function viewAccount(address account) - external view override returns (IexecLibCore_v5.Account memory) - { - return IexecLibCore_v5.Account(m_balances[account], m_frozens[account]); - } - - function token() - external view override returns (address) - { - return address(m_baseToken); - } - - function viewDeal(bytes32 _id) - external view override returns (IexecLibCore_v5.Deal memory deal) - { - return m_deals[_id]; - } - - function viewConsumed(bytes32 _id) - external view override returns (uint256 consumed) - { - return m_consumed[_id]; - } - - function viewPresigned(bytes32 _id) - external view override returns (address signer) - { - return m_presigned[_id]; - } - - function viewTask(bytes32 _taskid) - external view override returns (IexecLibCore_v5.Task memory) - { - return m_tasks[_taskid]; - } - - function viewContribution(bytes32 _taskid, address _worker) - external view override returns (IexecLibCore_v5.Contribution memory) - { - return m_contributions[_taskid][_worker]; - } - - function viewScore(address _worker) - external view override returns (uint256) - { - return m_workerScores[_worker]; - } - - function resultFor(bytes32 id) - external view override returns (bytes memory) - { - IexecLibCore_v5.Task storage task = m_tasks[id]; - require(task.status == IexecLibCore_v5.TaskStatusEnum.COMPLETED, 'task-pending'); - return task.resultsCallback; // Expansion - result separation - } - - function viewCategory(uint256 _catid) - external view override returns (IexecLibCore_v5.Category memory category) - { - return m_categories[_catid]; - } - - function countCategory() - external view override returns (uint256 count) - { - return m_categories.length; - } - - - function appregistry() - external view override returns (IRegistry) - { - return m_appregistry; - } - - function datasetregistry() - external view override returns (IRegistry) - { - return m_datasetregistry; - } - - function workerpoolregistry() - external view override returns (IRegistry) - { - return m_workerpoolregistry; - } - - function teebroker() - external view override returns (address) - { - return m_teebroker; - } - - function callbackgas() - external view override returns (uint256) - { - return m_callbackgas; - } - - function contribution_deadline_ratio() - external view override returns (uint256) - { - return CONTRIBUTION_DEADLINE_RATIO; - } - - function reveal_deadline_ratio() - external view override returns (uint256) - { - return REVEAL_DEADLINE_RATIO; - } - - function final_deadline_ratio() - external view override returns (uint256) - { - return FINAL_DEADLINE_RATIO; - } - - function workerpool_stake_ratio() - external view override returns (uint256) - { - return WORKERPOOL_STAKE_RATIO; - } - - function kitty_ratio() - external view override returns (uint256) - { - return KITTY_RATIO; - } - - function kitty_min() - external view override returns (uint256) - { - return KITTY_MIN; - } - - function kitty_address() - external view override returns (address) - { - return KITTY_ADDRESS; - } - - function groupmember_purpose() - external view override returns (uint256) - { - return GROUPMEMBER_PURPOSE; - } - - function eip712domain_separator() - external view override returns (bytes32) - { - return EIP712DOMAIN_SEPARATOR; - } -} diff --git a/contracts/modules/delegates/IexecERC20Delegate.sol b/contracts/modules/delegates/IexecERC20Delegate.sol deleted file mode 100644 index 937079e83..000000000 --- a/contracts/modules/delegates/IexecERC20Delegate.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -/****************************************************************************** - * Copyright 2020 IEXEC BLOCKCHAIN TECH * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - ******************************************************************************/ - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "./IexecERC20Core.sol"; -import "../DelegateBase.sol"; -import "../interfaces/IexecERC20.sol"; -import "../interfaces/IexecTokenSpender.sol"; - - -contract IexecERC20Delegate is IexecERC20, DelegateBase, IexecERC20Core -{ - function transfer(address recipient, uint256 amount) - external override returns (bool) - { - _transfer(_msgSender(), recipient, amount); - return true; - } - - function approve(address spender, uint256 value) - external override returns (bool) - { - _approve(_msgSender(), spender, value); - return true; - } - - function approveAndCall(address spender, uint256 value, bytes calldata extraData) - external override returns (bool) - { - _approve(_msgSender(), spender, value); - require(IexecTokenSpender(spender).receiveApproval(_msgSender(), value, address(this), extraData), 'approval-refused'); - return true; - } - - function transferFrom(address sender, address recipient, uint256 amount) - external override returns (bool) - { - _transfer(sender, recipient, amount); - _approve(sender, _msgSender(), m_allowances[sender][_msgSender()].sub(amount)); - return true; - } - - function increaseAllowance(address spender, uint256 addedValue) - external override returns (bool) - { - _approve(_msgSender(), spender, m_allowances[_msgSender()][spender].add(addedValue)); - return true; - } - - - function decreaseAllowance(address spender, uint256 subtractedValue) - external override returns (bool) - { - _approve(_msgSender(), spender, m_allowances[_msgSender()][spender].sub(subtractedValue)); - return true; - } -} diff --git a/contracts/modules/delegates/IexecEscrowNativeDelegate.sol b/contracts/modules/delegates/IexecEscrowNativeDelegate.sol deleted file mode 100644 index 358dc2c71..000000000 --- a/contracts/modules/delegates/IexecEscrowNativeDelegate.sol +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -/****************************************************************************** - * Copyright 2020 IEXEC BLOCKCHAIN TECH * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - ******************************************************************************/ - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "./IexecERC20Core.sol"; -import "../DelegateBase.sol"; -import "../interfaces/IexecEscrowNative.sol"; - - -contract IexecEscrowNativeDelegate is IexecEscrowNative, DelegateBase, IexecERC20Core -{ - using SafeMathExtended for uint256; - - uint256 internal constant nRLCtoWei = 10 ** 9; - /*************************************************************************** - * Escrow methods: public * - ***************************************************************************/ - receive() - external override payable - { - _deposit(_msgSender()); - } - - fallback() - external override payable - { - _deposit(_msgSender()); - } - - function deposit() - external override payable returns (bool) - { - _deposit(_msgSender()); - return true; - } - - function depositFor(address target) - external override payable returns (bool) - { - _deposit(target); - return true; - } - - function depositForArray(uint256[] calldata amounts, address[] calldata targets) - external override payable returns (bool) - { - require(amounts.length == targets.length, 'invalid-array-length'); - uint256 remaining = msg.value; - for (uint i = 0; i < amounts.length; ++i) - { - _mint(targets[i], amounts[i]); - remaining = remaining.sub(amounts[i].mul(nRLCtoWei)); - } - _withdraw(_msgSender(), remaining); - return true; - } - - function withdraw(uint256 amount) - external override returns (bool) - { - _burn(_msgSender(), amount); - _withdraw(_msgSender(), amount.mul(nRLCtoWei)); - return true; - } - - function withdrawTo(uint256 amount, address target) - external override returns (bool) - { - _burn(_msgSender(), amount); - _withdraw(target, amount.mul(nRLCtoWei)); - return true; - } - - function recover() - external override onlyOwner returns (uint256) - { - uint256 delta = address(this).balance.div(nRLCtoWei).sub(m_totalSupply); - _mint(owner(), delta); - return delta; - } - - function _deposit(address target) - internal - { - _mint(target, msg.value.div(nRLCtoWei)); - _withdraw(_msgSender(), msg.value.mod(nRLCtoWei)); - } - - function _withdraw(address to, uint256 value) - internal - { - (bool success, ) = to.call{value: value}(''); - require(success, 'native-transfer-failed'); - } -} diff --git a/contracts/modules/delegates/IexecEscrowTokenDelegate.sol b/contracts/modules/delegates/IexecEscrowTokenDelegate.sol deleted file mode 100644 index 12c0818b8..000000000 --- a/contracts/modules/delegates/IexecEscrowTokenDelegate.sol +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -/****************************************************************************** - * Copyright 2020 IEXEC BLOCKCHAIN TECH * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - ******************************************************************************/ - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "./IexecERC20Core.sol"; -import "../DelegateBase.sol"; -import "../interfaces/IexecEscrowToken.sol"; -import "../interfaces/IexecTokenSpender.sol"; - - -contract IexecEscrowTokenDelegate is IexecEscrowToken, IexecTokenSpender, DelegateBase, IexecERC20Core -{ - using SafeMathExtended for uint256; - - /*************************************************************************** - * Escrow methods: public * - ***************************************************************************/ - receive() - external override payable - { - revert('fallback-disabled'); - } - - fallback() - external override payable - { - revert('fallback-disabled'); - } - - function deposit(uint256 amount) - external override returns (bool) - { - _deposit(_msgSender(), amount); - _mint(_msgSender(), amount); - return true; - } - - function depositFor(uint256 amount, address target) - external override returns (bool) - { - _deposit(_msgSender(), amount); - _mint(target, amount); - return true; - } - - function depositForArray(uint256[] calldata amounts, address[] calldata targets) - external override returns (bool) - { - require(amounts.length == targets.length, 'invalid-array-length'); - for (uint i = 0; i < amounts.length; ++i) - { - _deposit(_msgSender(), amounts[i]); - _mint(targets[i], amounts[i]); - } - return true; - } - - function withdraw(uint256 amount) - external override returns (bool) - { - _burn(_msgSender(), amount); - _withdraw(_msgSender(), amount); - return true; - } - - function withdrawTo(uint256 amount, address target) - external override returns (bool) - { - _burn(_msgSender(), amount); - _withdraw(target, amount); - return true; - } - - function recover() - external override onlyOwner returns (uint256) - { - uint256 delta = m_baseToken.balanceOf(address(this)).sub(m_totalSupply); - _mint(owner(), delta); - return delta; - } - - // Token Spender (endpoint for approveAndCallback calls to the proxy) - function receiveApproval(address sender, uint256 amount, address token, bytes calldata) - external override returns (bool) - { - require(token == address(m_baseToken), 'wrong-token'); - _deposit(sender, amount); - _mint(sender, amount); - return true; - } - - function _deposit(address from, uint256 amount) - internal - { - require(m_baseToken.transferFrom(from, address(this), amount), 'failled-transferFrom'); - } - - function _withdraw(address to, uint256 amount) - internal - { - m_baseToken.transfer(to, amount); - } -} diff --git a/contracts/modules/delegates/IexecEscrowTokenSwapDelegate.sol b/contracts/modules/delegates/IexecEscrowTokenSwapDelegate.sol deleted file mode 100644 index a186cd871..000000000 --- a/contracts/modules/delegates/IexecEscrowTokenSwapDelegate.sol +++ /dev/null @@ -1,163 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -/****************************************************************************** - * Copyright 2020 IEXEC BLOCKCHAIN TECH * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - ******************************************************************************/ - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "./IexecERC20Core.sol"; -import "./SignatureVerifier.sol"; -import "../DelegateBase.sol"; -import "../interfaces/IexecEscrowTokenSwap.sol"; -import "../interfaces/IexecPoco1.sol"; - - -contract IexecEscrowTokenSwapDelegate is IexecEscrowTokenSwap, DelegateBase, IexecERC20Core, SignatureVerifier -{ - using SafeMathExtended for uint256; - using IexecLibOrders_v5 for IexecLibOrders_v5.AppOrder; - using IexecLibOrders_v5 for IexecLibOrders_v5.DatasetOrder; - using IexecLibOrders_v5 for IexecLibOrders_v5.WorkerpoolOrder; - using IexecLibOrders_v5 for IexecLibOrders_v5.RequestOrder; - - IUniswapV2Router02 internal constant router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); - - /*************************************************************************** - * Accessor * - ***************************************************************************/ - function UniswapV2Router() - external view override returns (IUniswapV2Router02) - { - return router; - } - - /*************************************************************************** - * Uniswap path - Internal * - ***************************************************************************/ - function _eth2token() - internal view returns (address[] memory) - { - address[] memory path = new address[](2); - path[0] = router.WETH(); - path[1] = address(m_baseToken); - return path; - } - - function _token2eth() - internal view returns (address[] memory) - { - address[] memory path = new address[](2); - path[0] = address(m_baseToken); - path[1] = router.WETH(); - return path; - } - - /*************************************************************************** - * Prediction methods - Public * - ***************************************************************************/ - function estimateDepositEthSent (uint256 eth ) external view override returns (uint256 token) { return router.getAmountsOut(eth, _eth2token())[1]; } - function estimateDepositTokenWanted(uint256 token) external view override returns (uint256 eth ) { return router.getAmountsIn (token, _eth2token())[0]; } - function estimateWithdrawTokenSent (uint256 token) external view override returns (uint256 eth ) { return router.getAmountsOut(token, _token2eth())[1]; } - function estimateWithdrawEthWanted (uint256 eth ) external view override returns (uint256 token) { return router.getAmountsIn (eth, _token2eth())[0]; } - - /*************************************************************************** - * Swapping methods - Public * - ***************************************************************************/ - receive() - external override payable - { - address sender = _msgSender(); - if (sender != address(router)) - { - _deposit(sender, msg.value, 0); - } - } - - fallback() - external override payable - { - revert('fallback-disabled'); - } - - function depositEth ( ) external override payable { _deposit(_msgSender(), msg.value, 0 ); } - function depositEthFor ( address target) external override payable { _deposit(target, msg.value, 0 ); } - function safeDepositEth ( uint256 minimum ) external override payable { _deposit(_msgSender(), msg.value, minimum); } - function safeDepositEthFor( uint256 minimum, address target) external override payable { _deposit(target, msg.value, minimum); } - function requestToken (uint256 amount ) external override payable { _request(_msgSender(), msg.value, amount ); } - function requestTokenFor (uint256 amount, address target) external override payable { _request(target, msg.value, amount ); } - function withdrawEth (uint256 amount ) external override { _withdraw(_msgSender(), amount, 0 ); } - function withdrawEthTo (uint256 amount, address target) external override { _withdraw(target, amount, 0 ); } - function safeWithdrawEth (uint256 amount, uint256 minimum ) external override { _withdraw(_msgSender(), amount, minimum); } - function safeWithdrawEthTo(uint256 amount, uint256 minimum, address target) external override { _withdraw(target, amount, minimum); } - - /*************************************************************************** - * Swapping methods - Internal * - ***************************************************************************/ - function _deposit(address target, uint256 value, uint256 minimum) - internal - { - uint256[] memory amounts = router.swapExactETHForTokens{value: value}(minimum, _eth2token(), address(this), now+1); - _mint(target, amounts[1]); - } - - function _request(address target, uint256 value, uint256 amount) - internal - { - uint256[] memory amounts = router.swapETHForExactTokens{value: value}(amount, _eth2token(), address(this), now+1); - _mint(target, amounts[1]); - // Refund remaining ETH - (bool success, ) = _msgSender().call{value: value.sub(amounts[0])}(''); - require(success, 'native-transfer-failed'); - } - - function _withdraw(address target, uint256 amount, uint256 minimum) - internal - { - m_baseToken.approve(address(router), amount); - uint256[] memory amounts = router.swapExactTokensForETH(amount, minimum, _token2eth(), target, now+1); - _burn(_msgSender(), amounts[0]); - } - - /*************************************************************************** - * Extra public methods * - ***************************************************************************/ - function matchOrdersWithEth( - IexecLibOrders_v5.AppOrder memory _apporder, - IexecLibOrders_v5.DatasetOrder memory _datasetorder, - IexecLibOrders_v5.WorkerpoolOrder memory _workerpoolorder, - IexecLibOrders_v5.RequestOrder memory _requestorder) - public payable override returns (bytes32) - { - uint256 volume; - volume = _apporder.volume.sub(m_consumed[keccak256(_toEthTypedStruct( _apporder.hash(), EIP712DOMAIN_SEPARATOR))]); - if (_datasetorder.dataset != address(0)) - volume = volume.min( _datasetorder.volume.sub(m_consumed[keccak256(_toEthTypedStruct( _datasetorder.hash(), EIP712DOMAIN_SEPARATOR))])); - volume = volume.min(_workerpoolorder.volume.sub(m_consumed[keccak256(_toEthTypedStruct(_workerpoolorder.hash(), EIP712DOMAIN_SEPARATOR))])); - volume = volume.min( _requestorder.volume.sub(m_consumed[keccak256(_toEthTypedStruct( _requestorder.hash(), EIP712DOMAIN_SEPARATOR))])); - - _request( - _requestorder.requester, - msg.value, - _apporder.appprice - .add(_datasetorder.dataset != address(0) ? _datasetorder.datasetprice : 0) - .add(_workerpoolorder.workerpoolprice) - .mul(volume) - ); - - return IexecPoco1(address(this)).matchOrders(_apporder, _datasetorder, _workerpoolorder, _requestorder); - } -} diff --git a/contracts/modules/delegates/IexecMaintenanceDelegate.sol b/contracts/modules/delegates/IexecMaintenanceDelegate.sol deleted file mode 100644 index 81f1b09d2..000000000 --- a/contracts/modules/delegates/IexecMaintenanceDelegate.sol +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -import "../DelegateBase.sol"; -import "../interfaces/IexecMaintenance.sol"; - -contract IexecMaintenanceDelegate is IexecMaintenance, DelegateBase -{ - using SafeMathExtended for uint256; - using IexecLibOrders_v5 for IexecLibOrders_v5.EIP712Domain; - - // TODO move this to DiamondInit.init(). - function configure( - address _token, - string calldata _name, - string calldata _symbol, - uint8 _decimal, - address _appregistryAddress, - address _datasetregistryAddress, - address _workerpoolregistryAddress, - address _v3_iexecHubAddress) - external override onlyOwner() - { - require(EIP712DOMAIN_SEPARATOR == bytes32(0), 'already-configured'); - EIP712DOMAIN_SEPARATOR = _domain().hash(); - - m_baseToken = IERC20(_token); - m_name = _name; - m_symbol = _symbol; - m_decimals = _decimal; - m_appregistry = IRegistry(_appregistryAddress); - m_datasetregistry = IRegistry(_datasetregistryAddress); - m_workerpoolregistry = IRegistry(_workerpoolregistryAddress); - m_v3_iexecHub = IexecHubInterface(_v3_iexecHubAddress); - m_callbackgas = 100000; - } - - function domain() - external view override returns (IexecLibOrders_v5.EIP712Domain memory) - { - return _domain(); - } - - function updateDomainSeparator() - external override - { - require(EIP712DOMAIN_SEPARATOR != bytes32(0), 'not-configured'); - EIP712DOMAIN_SEPARATOR = _domain().hash(); - } - - function importScore(address _worker) - external override - { - require(!m_v3_scoreImported[_worker], 'score-already-imported'); - m_workerScores[_worker] = m_workerScores[_worker].max(m_v3_iexecHub.viewScore(_worker)); - m_v3_scoreImported[_worker] = true; - } - - function setTeeBroker(address _teebroker) - external override onlyOwner() - { - m_teebroker = _teebroker; - } - - function setCallbackGas(uint256 _callbackgas) - external override onlyOwner() - { - m_callbackgas = _callbackgas; - } - - function _chainId() - internal pure returns (uint256 id) - { - assembly { id := chainid() } - } - - function _domain() - internal view returns (IexecLibOrders_v5.EIP712Domain memory) - { - return IexecLibOrders_v5.EIP712Domain({ - name: 'iExecODB' - , version: '5.0.0' - , chainId: _chainId() - , verifyingContract: address(this) - }); - } -} diff --git a/contracts/modules/delegates/SignatureVerifier.sol b/contracts/modules/delegates/SignatureVerifier.sol deleted file mode 100644 index 7714011a9..000000000 --- a/contracts/modules/delegates/SignatureVerifier.sol +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -/****************************************************************************** - * Copyright 2020 IEXEC BLOCKCHAIN TECH * - * * - * Licensed under the Apache License, Version 2.0 (the "License"); * - * you may not use this file except in compliance with the License. * - * You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, software * - * distributed under the License is distributed on an "AS IS" BASIS, * - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * - * See the License for the specific language governing permissions and * - * limitations under the License. * - ******************************************************************************/ - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "@iexec/solidity/contracts/ERC734/IERC734.sol"; -import "@iexec/solidity/contracts/ERC1271/IERC1271.sol"; -import "@iexec/solidity/contracts/ERC1654/IERC1654.sol"; -import "../DelegateBase.sol"; - - -contract SignatureVerifier is DelegateBase -{ - /** - * Prepare message/structure predicat used for signing - */ - function _toEthSignedMessage(bytes32 _msgHash) - internal pure returns (bytes memory) - { - return abi.encodePacked('\x19Ethereum Signed Message:\n32', _msgHash); - } - - function _toEthTypedStruct(bytes32 _structHash, bytes32 _domainHash) - internal pure returns (bytes memory) - { - return abi.encodePacked('\x19\x01', _domainHash, _structHash); - } - - /** - * recover EOA signature (support both 65 bytes traditional and 64 bytes format EIP2098 format) - */ - function _recover(bytes32 _hash, bytes memory _sign) - internal pure returns (address) - { - bytes32 r; - bytes32 s; - uint8 v; - - if (_sign.length == 65) // 65bytes: (r,s,v) form - { - assembly - { - r := mload(add(_sign, 0x20)) - s := mload(add(_sign, 0x40)) - v := byte(0, mload(add(_sign, 0x60))) - } - } - else if (_sign.length == 64) // 64bytes: (r,vs) form → see EIP2098 - { - assembly - { - r := mload(add(_sign, 0x20)) - s := and( mload(add(_sign, 0x40)), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - v := shr(7, byte(0, mload(add(_sign, 0x40)))) - } - } - else - { - revert('invalid-signature-format'); - } - - if (v < 27) v += 27; - require(v == 27 || v == 28, 'invalid-signature-v'); - return ecrecover(_hash, v, r, s); - } - - /** - * Check if contract exist, otherwize assumed to be EOA - */ - function _isContract(address account) - internal view returns (bool) - { - // According to EIP-1052, 0x0 is the value returned for not-yet created accounts - // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned - // for accounts without code, i.e. `keccak256('')` - bytes32 codehash; - bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; - // solhint-disable-next-line no-inline-assembly - assembly { codehash := extcodehash(account) } - return (codehash != accountHash && codehash != 0x0); - } - - /** - * Address to bytes32 casting to ERC734 - */ - function _addrToKey(address _addr) - internal pure returns (bytes32) - { - return bytes32(uint256(_addr)); - } - - /** - * Identity verification - */ - function _checkIdentity(address _identity, address _candidate, uint256 _purpose) - internal view returns (bool valid) - { - return _identity == _candidate || IERC734(_identity).keyHasPurpose(_addrToKey(_candidate), _purpose); // Simple address || ERC 734 identity contract - } - - function _checkPresignature(address _identity, bytes32 _hash) - internal view returns (bool) - { - return _identity != address(0) && _identity == m_presigned[_hash]; - } - - function _checkSignature(address _identity, bytes32 _hash, bytes memory _signature) - internal view returns (bool) - { - if (_isContract(_identity)) - { - try IERC1654(_identity).isValidSignature(_hash, _signature) returns (bytes4 value) - { - return value == IERC1654(0).isValidSignature.selector; - } catch (bytes memory /*lowLevelData*/) {} - - return false; - } - else - { - return _recover(_hash, _signature) == _identity; - } - } - - function _checkSignature(address _identity, bytes memory _predicat, bytes memory _signature) - internal view returns (bool) - { - if (_isContract(_identity)) - { - try IERC1271(_identity).isValidSignature(_predicat, _signature) returns (bytes4 value) - { - return value == IERC1271(0).isValidSignature.selector; - } - catch (bytes memory /*lowLevelData*/) {} - - try IERC1654(_identity).isValidSignature(keccak256(_predicat), _signature) returns (bytes4 value) - { - return value == IERC1654(0).isValidSignature.selector; - } - catch (bytes memory /*lowLevelData*/) {} - - return false; - } - else - { - return _recover(keccak256(_predicat), _signature) == _identity; - } - } - - function _checkPresignatureOrSignature(address _identity, bytes32 _hash, bytes memory _signature) - internal view returns (bool) - { - return _checkPresignature(_identity, _hash) || _checkSignature(_identity, _hash, _signature); - } - - function _checkPresignatureOrSignature(address _identity, bytes memory _predicat, bytes memory _signature) - internal view returns (bool) - { - return _checkPresignature(_identity, keccak256(_predicat)) || _checkSignature(_identity, _predicat, _signature); - } -} diff --git a/contracts/modules/facets/IexecAccessorsABILegacyFacet.sol b/contracts/modules/facets/IexecAccessorsABILegacyFacet.sol new file mode 100644 index 000000000..116614cf7 --- /dev/null +++ b/contracts/modules/facets/IexecAccessorsABILegacyFacet.sol @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: Apache-2.0 + +/****************************************************************************** + * Copyright 2020 IEXEC BLOCKCHAIN TECH * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "../FacetBase.sol"; +import "../interfaces/IexecAccessorsABILegacy.sol"; + +contract IexecAccessorsABILegacyFacet is IexecAccessorsABILegacy, FacetBase { + function viewDealABILegacy_pt1( + bytes32 _id + ) + external + view + override + returns (address, address, uint256, address, address, uint256, address, address, uint256) + { + IexecLibCore_v5.Deal memory deal = m_deals[_id]; + return ( + deal.app.pointer, + deal.app.owner, + deal.app.price, + deal.dataset.pointer, + deal.dataset.owner, + deal.dataset.price, + deal.workerpool.pointer, + deal.workerpool.owner, + deal.workerpool.price + ); + } + + function viewDealABILegacy_pt2( + bytes32 _id + ) external view override returns (uint256, bytes32, address, address, address, string memory) { + IexecLibCore_v5.Deal memory deal = m_deals[_id]; + return (deal.trust, deal.tag, deal.requester, deal.beneficiary, deal.callback, deal.params); + } + + function viewConfigABILegacy( + bytes32 _id + ) external view override returns (uint256, uint256, uint256, uint256, uint256, uint256) { + IexecLibCore_v5.Deal memory deal = m_deals[_id]; + return ( + deal.category, + deal.startTime, + deal.botFirst, + deal.botSize, + deal.workerStake, + deal.schedulerRewardRatio + ); + } + + function viewAccountABILegacy( + address account + ) external view override returns (uint256, uint256) { + return (m_balances[account], m_frozens[account]); + } + + function viewTaskABILegacy( + bytes32 _taskid + ) + external + view + override + returns ( + IexecLibCore_v5.TaskStatusEnum, + bytes32, + uint256, + uint256, + uint256, + uint256, + uint256, + bytes32, + uint256, + uint256, + address[] memory, + bytes memory + ) + { + IexecLibCore_v5.Task memory task = m_tasks[_taskid]; + return ( + task.status, + task.dealid, + task.idx, + task.timeref, + task.contributionDeadline, + task.revealDeadline, + task.finalDeadline, + task.consensusValue, + task.revealCounter, + task.winnerCounter, + task.contributors, + task.results + ); + } + + function viewContributionABILegacy( + bytes32 _taskid, + address _worker + ) + external + view + override + returns (IexecLibCore_v5.ContributionStatusEnum, bytes32, bytes32, address) + { + IexecLibCore_v5.Contribution memory contribution = m_contributions[_taskid][_worker]; + return ( + contribution.status, + contribution.resultHash, + contribution.resultSeal, + contribution.enclaveChallenge + ); + } + + function viewCategoryABILegacy( + uint256 _catid + ) external view override returns (string memory, string memory, uint256) { + IexecLibCore_v5.Category memory category = m_categories[_catid]; + return (category.name, category.description, category.workClockTimeRef); + } +} diff --git a/contracts/modules/facets/IexecAccessorsFacet.sol b/contracts/modules/facets/IexecAccessorsFacet.sol new file mode 100644 index 000000000..d3f653e54 --- /dev/null +++ b/contracts/modules/facets/IexecAccessorsFacet.sol @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: Apache-2.0 + +/****************************************************************************** + * Copyright 2020 IEXEC BLOCKCHAIN TECH * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "../FacetBase.sol"; +import "../interfaces/IexecAccessors.sol"; + +contract IexecAccessorsFacet is IexecAccessors, FacetBase { + function name() external view override returns (string memory) { + return m_name; + } + + function symbol() external view override returns (string memory) { + return m_symbol; + } + + function decimals() external view override returns (uint8) { + return m_decimals; + } + + function totalSupply() external view override returns (uint256) { + return m_totalSupply; + } + + function balanceOf(address account) external view override returns (uint256) { + return m_balances[account]; + } + + function frozenOf(address account) external view override returns (uint256) { + return m_frozens[account]; + } + + function allowance(address account, address spender) external view override returns (uint256) { + return m_allowances[account][spender]; + } + + function viewAccount( + address account + ) external view override returns (IexecLibCore_v5.Account memory) { + return IexecLibCore_v5.Account(m_balances[account], m_frozens[account]); + } + + function token() external view override returns (address) { + return address(m_baseToken); + } + + function viewDeal( + bytes32 _id + ) external view override returns (IexecLibCore_v5.Deal memory deal) { + return m_deals[_id]; + } + + function viewConsumed(bytes32 _id) external view override returns (uint256 consumed) { + return m_consumed[_id]; + } + + function viewPresigned(bytes32 _id) external view override returns (address signer) { + return m_presigned[_id]; + } + + function viewTask( + bytes32 _taskid + ) external view override returns (IexecLibCore_v5.Task memory) { + return m_tasks[_taskid]; + } + + function viewContribution( + bytes32 _taskid, + address _worker + ) external view override returns (IexecLibCore_v5.Contribution memory) { + return m_contributions[_taskid][_worker]; + } + + function viewScore(address _worker) external view override returns (uint256) { + return m_workerScores[_worker]; + } + + function resultFor(bytes32 id) external view override returns (bytes memory) { + IexecLibCore_v5.Task storage task = m_tasks[id]; + require(task.status == IexecLibCore_v5.TaskStatusEnum.COMPLETED, "task-pending"); + return task.resultsCallback; // Expansion - result separation + } + + function viewCategory( + uint256 _catid + ) external view override returns (IexecLibCore_v5.Category memory category) { + return m_categories[_catid]; + } + + function countCategory() external view override returns (uint256 count) { + return m_categories.length; + } + + function appregistry() external view override returns (IRegistry) { + return m_appregistry; + } + + function datasetregistry() external view override returns (IRegistry) { + return m_datasetregistry; + } + + function workerpoolregistry() external view override returns (IRegistry) { + return m_workerpoolregistry; + } + + function teebroker() external view override returns (address) { + return m_teebroker; + } + + function callbackgas() external view override returns (uint256) { + return m_callbackgas; + } + + function contribution_deadline_ratio() external view override returns (uint256) { + return CONTRIBUTION_DEADLINE_RATIO; + } + + function reveal_deadline_ratio() external view override returns (uint256) { + return REVEAL_DEADLINE_RATIO; + } + + function final_deadline_ratio() external view override returns (uint256) { + return FINAL_DEADLINE_RATIO; + } + + function workerpool_stake_ratio() external view override returns (uint256) { + return WORKERPOOL_STAKE_RATIO; + } + + function kitty_ratio() external view override returns (uint256) { + return KITTY_RATIO; + } + + function kitty_min() external view override returns (uint256) { + return KITTY_MIN; + } + + function kitty_address() external view override returns (address) { + return KITTY_ADDRESS; + } + + function groupmember_purpose() external view override returns (uint256) { + return GROUPMEMBER_PURPOSE; + } + + function eip712domain_separator() external view override returns (bytes32) { + return EIP712DOMAIN_SEPARATOR; + } +} diff --git a/contracts/modules/delegates/IexecCategoryManagerDelegate.sol b/contracts/modules/facets/IexecCategoryManagerFacet.sol similarity index 71% rename from contracts/modules/delegates/IexecCategoryManagerDelegate.sol rename to contracts/modules/facets/IexecCategoryManagerFacet.sol index 86c5acf5a..ae028dea6 100644 --- a/contracts/modules/delegates/IexecCategoryManagerDelegate.sol +++ b/contracts/modules/facets/IexecCategoryManagerFacet.sol @@ -19,35 +19,23 @@ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; -import "../DelegateBase.sol"; +import "../FacetBase.sol"; import "../interfaces/IexecCategoryManager.sol"; +contract IexecCategoryManagerFacet is IexecCategoryManager, FacetBase { + /** + * Methods + */ + function createCategory( + string calldata name, + string calldata description, + uint256 workClockTimeRef + ) external override onlyOwner returns (uint256) { + m_categories.push(IexecLibCore_v5.Category(name, description, workClockTimeRef)); -contract IexecCategoryManagerDelegate is IexecCategoryManager, DelegateBase -{ - /** - * Methods - */ - function createCategory( - string calldata name, - string calldata description, - uint256 workClockTimeRef) - external override onlyOwner returns (uint256) - { - m_categories.push(IexecLibCore_v5.Category( - name, - description, - workClockTimeRef - )); + uint256 catid = m_categories.length - 1; - uint256 catid = m_categories.length - 1; - - emit CreateCategory( - catid, - name, - description, - workClockTimeRef - ); - return catid; - } + emit CreateCategory(catid, name, description, workClockTimeRef); + return catid; + } } diff --git a/contracts/modules/delegates/IexecERC20Core.sol b/contracts/modules/facets/IexecERC20Core.sol similarity index 96% rename from contracts/modules/delegates/IexecERC20Core.sol rename to contracts/modules/facets/IexecERC20Core.sol index c0ee1d1bd..59a461f7b 100644 --- a/contracts/modules/delegates/IexecERC20Core.sol +++ b/contracts/modules/facets/IexecERC20Core.sol @@ -4,9 +4,9 @@ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; -import "../DelegateBase.sol"; +import "../FacetBase.sol"; -contract IexecERC20Core is DelegateBase { +contract IexecERC20Core is FacetBase { using SafeMathExtended for uint256; event Transfer(address indexed from, address indexed to, uint256 value); diff --git a/contracts/modules/facets/IexecERC20Facet.sol b/contracts/modules/facets/IexecERC20Facet.sol new file mode 100644 index 000000000..6bd9c6c7a --- /dev/null +++ b/contracts/modules/facets/IexecERC20Facet.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 + +/****************************************************************************** + * Copyright 2020 IEXEC BLOCKCHAIN TECH * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "./IexecERC20Core.sol"; +import "../FacetBase.sol"; +import "../interfaces/IexecERC20.sol"; +import "../interfaces/IexecTokenSpender.sol"; + +contract IexecERC20Facet is IexecERC20, FacetBase, IexecERC20Core { + function transfer(address recipient, uint256 amount) external override returns (bool) { + _transfer(_msgSender(), recipient, amount); + return true; + } + + function approve(address spender, uint256 value) external override returns (bool) { + _approve(_msgSender(), spender, value); + return true; + } + + function approveAndCall( + address spender, + uint256 value, + bytes calldata extraData + ) external override returns (bool) { + _approve(_msgSender(), spender, value); + require( + IexecTokenSpender(spender).receiveApproval( + _msgSender(), + value, + address(this), + extraData + ), + "approval-refused" + ); + return true; + } + + function transferFrom( + address sender, + address recipient, + uint256 amount + ) external override returns (bool) { + _transfer(sender, recipient, amount); + _approve(sender, _msgSender(), m_allowances[sender][_msgSender()].sub(amount)); + return true; + } + + function increaseAllowance( + address spender, + uint256 addedValue + ) external override returns (bool) { + _approve(_msgSender(), spender, m_allowances[_msgSender()][spender].add(addedValue)); + return true; + } + + function decreaseAllowance( + address spender, + uint256 subtractedValue + ) external override returns (bool) { + _approve(_msgSender(), spender, m_allowances[_msgSender()][spender].sub(subtractedValue)); + return true; + } +} diff --git a/contracts/modules/delegates/IexecEscrow.v8.sol b/contracts/modules/facets/IexecEscrow.v8.sol similarity index 97% rename from contracts/modules/delegates/IexecEscrow.v8.sol rename to contracts/modules/facets/IexecEscrow.v8.sol index 540459909..9018742d2 100644 --- a/contracts/modules/delegates/IexecEscrow.v8.sol +++ b/contracts/modules/facets/IexecEscrow.v8.sol @@ -3,12 +3,12 @@ pragma solidity ^0.8.0; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; /** * @title Manage (lock/unlock/reward/seize) user funds. */ -contract IexecEscrow is DelegateBase { +contract IexecEscrow is FacetBase { event Transfer(address indexed from, address indexed to, uint256 value); event Lock(address owner, uint256 amount); event Unlock(address owner, uint256 amount); diff --git a/contracts/modules/facets/IexecEscrowNativeFacet.sol b/contracts/modules/facets/IexecEscrowNativeFacet.sol new file mode 100644 index 000000000..c2afe779e --- /dev/null +++ b/contracts/modules/facets/IexecEscrowNativeFacet.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: Apache-2.0 + +/****************************************************************************** + * Copyright 2020 IEXEC BLOCKCHAIN TECH * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "./IexecERC20Core.sol"; +import "../FacetBase.sol"; +import "../interfaces/IexecEscrowNative.sol"; + +contract IexecEscrowNativeFacet is IexecEscrowNative, FacetBase, IexecERC20Core { + using SafeMathExtended for uint256; + + uint256 internal constant nRLCtoWei = 10 ** 9; + /*************************************************************************** + * Escrow methods: public * + ***************************************************************************/ + receive() external payable override { + _deposit(_msgSender()); + } + + fallback() external payable override { + _deposit(_msgSender()); + } + + function deposit() external payable override returns (bool) { + _deposit(_msgSender()); + return true; + } + + function depositFor(address target) external payable override returns (bool) { + _deposit(target); + return true; + } + + function depositForArray( + uint256[] calldata amounts, + address[] calldata targets + ) external payable override returns (bool) { + require(amounts.length == targets.length, "invalid-array-length"); + uint256 remaining = msg.value; + for (uint i = 0; i < amounts.length; ++i) { + _mint(targets[i], amounts[i]); + remaining = remaining.sub(amounts[i].mul(nRLCtoWei)); + } + _withdraw(_msgSender(), remaining); + return true; + } + + function withdraw(uint256 amount) external override returns (bool) { + _burn(_msgSender(), amount); + _withdraw(_msgSender(), amount.mul(nRLCtoWei)); + return true; + } + + function withdrawTo(uint256 amount, address target) external override returns (bool) { + _burn(_msgSender(), amount); + _withdraw(target, amount.mul(nRLCtoWei)); + return true; + } + + function recover() external override onlyOwner returns (uint256) { + uint256 delta = address(this).balance.div(nRLCtoWei).sub(m_totalSupply); + _mint(owner(), delta); + return delta; + } + + function _deposit(address target) internal { + _mint(target, msg.value.div(nRLCtoWei)); + _withdraw(_msgSender(), msg.value.mod(nRLCtoWei)); + } + + function _withdraw(address to, uint256 value) internal { + (bool success, ) = to.call{value: value}(""); + require(success, "native-transfer-failed"); + } +} diff --git a/contracts/modules/facets/IexecEscrowTokenFacet.sol b/contracts/modules/facets/IexecEscrowTokenFacet.sol new file mode 100644 index 000000000..f8368e834 --- /dev/null +++ b/contracts/modules/facets/IexecEscrowTokenFacet.sol @@ -0,0 +1,103 @@ +// SPDX-License-Identifier: Apache-2.0 + +/****************************************************************************** + * Copyright 2020 IEXEC BLOCKCHAIN TECH * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "./IexecERC20Core.sol"; +import "../FacetBase.sol"; +import "../interfaces/IexecEscrowToken.sol"; +import "../interfaces/IexecTokenSpender.sol"; + +contract IexecEscrowTokenFacet is IexecEscrowToken, IexecTokenSpender, FacetBase, IexecERC20Core { + using SafeMathExtended for uint256; + + /*************************************************************************** + * Escrow methods: public * + ***************************************************************************/ + receive() external payable override { + revert("fallback-disabled"); + } + + fallback() external payable override { + revert("fallback-disabled"); + } + + function deposit(uint256 amount) external override returns (bool) { + _deposit(_msgSender(), amount); + _mint(_msgSender(), amount); + return true; + } + + function depositFor(uint256 amount, address target) external override returns (bool) { + _deposit(_msgSender(), amount); + _mint(target, amount); + return true; + } + + function depositForArray( + uint256[] calldata amounts, + address[] calldata targets + ) external override returns (bool) { + require(amounts.length == targets.length, "invalid-array-length"); + for (uint i = 0; i < amounts.length; ++i) { + _deposit(_msgSender(), amounts[i]); + _mint(targets[i], amounts[i]); + } + return true; + } + + function withdraw(uint256 amount) external override returns (bool) { + _burn(_msgSender(), amount); + _withdraw(_msgSender(), amount); + return true; + } + + function withdrawTo(uint256 amount, address target) external override returns (bool) { + _burn(_msgSender(), amount); + _withdraw(target, amount); + return true; + } + + function recover() external override onlyOwner returns (uint256) { + uint256 delta = m_baseToken.balanceOf(address(this)).sub(m_totalSupply); + _mint(owner(), delta); + return delta; + } + + // Token Spender (endpoint for approveAndCallback calls to the proxy) + function receiveApproval( + address sender, + uint256 amount, + address token, + bytes calldata + ) external override returns (bool) { + require(token == address(m_baseToken), "wrong-token"); + _deposit(sender, amount); + _mint(sender, amount); + return true; + } + + function _deposit(address from, uint256 amount) internal { + require(m_baseToken.transferFrom(from, address(this), amount), "failled-transferFrom"); + } + + function _withdraw(address to, uint256 amount) internal { + m_baseToken.transfer(to, amount); + } +} diff --git a/contracts/modules/facets/IexecEscrowTokenSwapFacet.sol b/contracts/modules/facets/IexecEscrowTokenSwapFacet.sol new file mode 100644 index 000000000..cf2b0cb91 --- /dev/null +++ b/contracts/modules/facets/IexecEscrowTokenSwapFacet.sol @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: Apache-2.0 + +/****************************************************************************** + * Copyright 2020 IEXEC BLOCKCHAIN TECH * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "./IexecERC20Core.sol"; +import "./SignatureVerifier.sol"; +import "../FacetBase.sol"; +import "../interfaces/IexecEscrowTokenSwap.sol"; +import "../interfaces/IexecPoco1.sol"; + +contract IexecEscrowTokenSwapFacet is + IexecEscrowTokenSwap, + FacetBase, + IexecERC20Core, + SignatureVerifier +{ + using SafeMathExtended for uint256; + using IexecLibOrders_v5 for IexecLibOrders_v5.AppOrder; + using IexecLibOrders_v5 for IexecLibOrders_v5.DatasetOrder; + using IexecLibOrders_v5 for IexecLibOrders_v5.WorkerpoolOrder; + using IexecLibOrders_v5 for IexecLibOrders_v5.RequestOrder; + + IUniswapV2Router02 internal constant router = + IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); + + /*************************************************************************** + * Accessor * + ***************************************************************************/ + function UniswapV2Router() external view override returns (IUniswapV2Router02) { + return router; + } + + /*************************************************************************** + * Uniswap path - Internal * + ***************************************************************************/ + function _eth2token() internal view returns (address[] memory) { + address[] memory path = new address[](2); + path[0] = router.WETH(); + path[1] = address(m_baseToken); + return path; + } + + function _token2eth() internal view returns (address[] memory) { + address[] memory path = new address[](2); + path[0] = address(m_baseToken); + path[1] = router.WETH(); + return path; + } + + /*************************************************************************** + * Prediction methods - Public * + ***************************************************************************/ + function estimateDepositEthSent(uint256 eth) external view override returns (uint256 token) { + return router.getAmountsOut(eth, _eth2token())[1]; + } + function estimateDepositTokenWanted( + uint256 token + ) external view override returns (uint256 eth) { + return router.getAmountsIn(token, _eth2token())[0]; + } + function estimateWithdrawTokenSent(uint256 token) external view override returns (uint256 eth) { + return router.getAmountsOut(token, _token2eth())[1]; + } + function estimateWithdrawEthWanted(uint256 eth) external view override returns (uint256 token) { + return router.getAmountsIn(eth, _token2eth())[0]; + } + + /*************************************************************************** + * Swapping methods - Public * + ***************************************************************************/ + receive() external payable override { + address sender = _msgSender(); + if (sender != address(router)) { + _deposit(sender, msg.value, 0); + } + } + + fallback() external payable override { + revert("fallback-disabled"); + } + + function depositEth() external payable override { + _deposit(_msgSender(), msg.value, 0); + } + function depositEthFor(address target) external payable override { + _deposit(target, msg.value, 0); + } + function safeDepositEth(uint256 minimum) external payable override { + _deposit(_msgSender(), msg.value, minimum); + } + function safeDepositEthFor(uint256 minimum, address target) external payable override { + _deposit(target, msg.value, minimum); + } + function requestToken(uint256 amount) external payable override { + _request(_msgSender(), msg.value, amount); + } + function requestTokenFor(uint256 amount, address target) external payable override { + _request(target, msg.value, amount); + } + function withdrawEth(uint256 amount) external override { + _withdraw(_msgSender(), amount, 0); + } + function withdrawEthTo(uint256 amount, address target) external override { + _withdraw(target, amount, 0); + } + function safeWithdrawEth(uint256 amount, uint256 minimum) external override { + _withdraw(_msgSender(), amount, minimum); + } + function safeWithdrawEthTo(uint256 amount, uint256 minimum, address target) external override { + _withdraw(target, amount, minimum); + } + + /*************************************************************************** + * Swapping methods - Internal * + ***************************************************************************/ + function _deposit(address target, uint256 value, uint256 minimum) internal { + uint256[] memory amounts = router.swapExactETHForTokens{value: value}( + minimum, + _eth2token(), + address(this), + now + 1 + ); + _mint(target, amounts[1]); + } + + function _request(address target, uint256 value, uint256 amount) internal { + uint256[] memory amounts = router.swapETHForExactTokens{value: value}( + amount, + _eth2token(), + address(this), + now + 1 + ); + _mint(target, amounts[1]); + // Refund remaining ETH + (bool success, ) = _msgSender().call{value: value.sub(amounts[0])}(""); + require(success, "native-transfer-failed"); + } + + function _withdraw(address target, uint256 amount, uint256 minimum) internal { + m_baseToken.approve(address(router), amount); + uint256[] memory amounts = router.swapExactTokensForETH( + amount, + minimum, + _token2eth(), + target, + now + 1 + ); + _burn(_msgSender(), amounts[0]); + } + + /*************************************************************************** + * Extra public methods * + ***************************************************************************/ + function matchOrdersWithEth( + IexecLibOrders_v5.AppOrder memory _apporder, + IexecLibOrders_v5.DatasetOrder memory _datasetorder, + IexecLibOrders_v5.WorkerpoolOrder memory _workerpoolorder, + IexecLibOrders_v5.RequestOrder memory _requestorder + ) public payable override returns (bytes32) { + uint256 volume; + volume = _apporder.volume.sub( + m_consumed[keccak256(_toEthTypedStruct(_apporder.hash(), EIP712DOMAIN_SEPARATOR))] + ); + if (_datasetorder.dataset != address(0)) + volume = volume.min( + _datasetorder.volume.sub( + m_consumed[ + keccak256(_toEthTypedStruct(_datasetorder.hash(), EIP712DOMAIN_SEPARATOR)) + ] + ) + ); + volume = volume.min( + _workerpoolorder.volume.sub( + m_consumed[ + keccak256(_toEthTypedStruct(_workerpoolorder.hash(), EIP712DOMAIN_SEPARATOR)) + ] + ) + ); + volume = volume.min( + _requestorder.volume.sub( + m_consumed[ + keccak256(_toEthTypedStruct(_requestorder.hash(), EIP712DOMAIN_SEPARATOR)) + ] + ) + ); + + _request( + _requestorder.requester, + msg.value, + _apporder + .appprice + .add(_datasetorder.dataset != address(0) ? _datasetorder.datasetprice : 0) + .add(_workerpoolorder.workerpoolprice) + .mul(volume) + ); + + return + IexecPoco1(address(this)).matchOrders( + _apporder, + _datasetorder, + _workerpoolorder, + _requestorder + ); + } +} diff --git a/contracts/modules/delegates/IexecMaintenanceExtraDelegate.sol b/contracts/modules/facets/IexecMaintenanceExtraFacet.sol similarity index 73% rename from contracts/modules/delegates/IexecMaintenanceExtraDelegate.sol rename to contracts/modules/facets/IexecMaintenanceExtraFacet.sol index 39d6aa861..da617f4ee 100644 --- a/contracts/modules/delegates/IexecMaintenanceExtraDelegate.sol +++ b/contracts/modules/facets/IexecMaintenanceExtraFacet.sol @@ -19,20 +19,17 @@ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; -import "../DelegateBase.sol"; +import "../FacetBase.sol"; import "../interfaces/IexecMaintenanceExtra.sol"; - -contract IexecMaintenanceExtraDelegate is IexecMaintenanceExtra, DelegateBase -{ - function changeRegistries( - address _appregistryAddress, - address _datasetregistryAddress, - address _workerpoolregistryAddress) - external override onlyOwner() - { - m_appregistry = IRegistry(_appregistryAddress); - m_datasetregistry = IRegistry(_datasetregistryAddress); - m_workerpoolregistry = IRegistry(_workerpoolregistryAddress); - } +contract IexecMaintenanceExtraFacet is IexecMaintenanceExtra, FacetBase { + function changeRegistries( + address _appregistryAddress, + address _datasetregistryAddress, + address _workerpoolregistryAddress + ) external override onlyOwner { + m_appregistry = IRegistry(_appregistryAddress); + m_datasetregistry = IRegistry(_datasetregistryAddress); + m_workerpoolregistry = IRegistry(_workerpoolregistryAddress); + } } diff --git a/contracts/modules/facets/IexecMaintenanceFacet.sol b/contracts/modules/facets/IexecMaintenanceFacet.sol new file mode 100644 index 000000000..ec611f478 --- /dev/null +++ b/contracts/modules/facets/IexecMaintenanceFacet.sol @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +import "../FacetBase.sol"; +import "../interfaces/IexecMaintenance.sol"; + +contract IexecMaintenanceFacet is IexecMaintenance, FacetBase { + using SafeMathExtended for uint256; + using IexecLibOrders_v5 for IexecLibOrders_v5.EIP712Domain; + + // TODO move this to DiamondInit.init(). + function configure( + address _token, + string calldata _name, + string calldata _symbol, + uint8 _decimal, + address _appregistryAddress, + address _datasetregistryAddress, + address _workerpoolregistryAddress, + address _v3_iexecHubAddress + ) external override onlyOwner { + require(EIP712DOMAIN_SEPARATOR == bytes32(0), "already-configured"); + EIP712DOMAIN_SEPARATOR = _domain().hash(); + + m_baseToken = IERC20(_token); + m_name = _name; + m_symbol = _symbol; + m_decimals = _decimal; + m_appregistry = IRegistry(_appregistryAddress); + m_datasetregistry = IRegistry(_datasetregistryAddress); + m_workerpoolregistry = IRegistry(_workerpoolregistryAddress); + m_v3_iexecHub = IexecHubInterface(_v3_iexecHubAddress); + m_callbackgas = 100000; + } + + function domain() external view override returns (IexecLibOrders_v5.EIP712Domain memory) { + return _domain(); + } + + function updateDomainSeparator() external override { + require(EIP712DOMAIN_SEPARATOR != bytes32(0), "not-configured"); + EIP712DOMAIN_SEPARATOR = _domain().hash(); + } + + function importScore(address _worker) external override { + require(!m_v3_scoreImported[_worker], "score-already-imported"); + m_workerScores[_worker] = m_workerScores[_worker].max(m_v3_iexecHub.viewScore(_worker)); + m_v3_scoreImported[_worker] = true; + } + + function setTeeBroker(address _teebroker) external override onlyOwner { + m_teebroker = _teebroker; + } + + function setCallbackGas(uint256 _callbackgas) external override onlyOwner { + m_callbackgas = _callbackgas; + } + + function _chainId() internal pure returns (uint256 id) { + assembly { + id := chainid() + } + } + + function _domain() internal view returns (IexecLibOrders_v5.EIP712Domain memory) { + return + IexecLibOrders_v5.EIP712Domain({ + name: "iExecODB", + version: "5.0.0", + chainId: _chainId(), + verifyingContract: address(this) + }); + } +} diff --git a/contracts/modules/delegates/IexecOrderManagementDelegate.sol b/contracts/modules/facets/IexecOrderManagementFacet.sol similarity index 97% rename from contracts/modules/delegates/IexecOrderManagementDelegate.sol rename to contracts/modules/facets/IexecOrderManagementFacet.sol index 3ebba8a13..c95c74d79 100644 --- a/contracts/modules/delegates/IexecOrderManagementDelegate.sol +++ b/contracts/modules/facets/IexecOrderManagementFacet.sol @@ -5,11 +5,11 @@ pragma solidity ^0.8.0; import {IERC5313} from "@openzeppelin/contracts-v5/interfaces/IERC5313.sol"; import {SignatureVerifier} from "./SignatureVerifier.v8.sol"; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; import {IexecOrderManagement} from "../interfaces/IexecOrderManagement.v8.sol"; import {IexecLibOrders_v5} from "../../libs/IexecLibOrders_v5.sol"; -contract IexecOrderManagementDelegate is IexecOrderManagement, DelegateBase, SignatureVerifier { +contract IexecOrderManagementFacet is IexecOrderManagement, FacetBase, SignatureVerifier { using IexecLibOrders_v5 for IexecLibOrders_v5.AppOrder; using IexecLibOrders_v5 for IexecLibOrders_v5.DatasetOrder; using IexecLibOrders_v5 for IexecLibOrders_v5.WorkerpoolOrder; diff --git a/contracts/modules/delegates/IexecPoco1Delegate.sol b/contracts/modules/facets/IexecPoco1Facet.sol similarity index 98% rename from contracts/modules/delegates/IexecPoco1Delegate.sol rename to contracts/modules/facets/IexecPoco1Facet.sol index 066cdf0a4..db7880f02 100644 --- a/contracts/modules/delegates/IexecPoco1Delegate.sol +++ b/contracts/modules/facets/IexecPoco1Facet.sol @@ -9,10 +9,10 @@ import {Math} from "@openzeppelin/contracts-v5/utils/math/Math.sol"; import {IexecLibCore_v5} from "../../libs/IexecLibCore_v5.sol"; import {IexecLibOrders_v5} from "../../libs/IexecLibOrders_v5.sol"; import {IWorkerpool} from "../../registries/workerpools/IWorkerpool.v8.sol"; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; import {IexecPoco1} from "../interfaces/IexecPoco1.v8.sol"; import {IexecEscrow} from "./IexecEscrow.v8.sol"; -import {IexecPocoCommonDelegate} from "./IexecPocoCommonDelegate.sol"; +import {IexecPocoCommonFacet} from "./IexecPocoCommonFacet.sol"; import {SignatureVerifier} from "./SignatureVerifier.v8.sol"; struct Matching { @@ -26,12 +26,12 @@ struct Matching { bool hasDataset; } -contract IexecPoco1Delegate is +contract IexecPoco1Facet is IexecPoco1, - DelegateBase, + FacetBase, IexecEscrow, SignatureVerifier, - IexecPocoCommonDelegate + IexecPocoCommonFacet { using Math for uint256; using IexecLibOrders_v5 for IexecLibOrders_v5.AppOrder; diff --git a/contracts/modules/delegates/IexecPoco2Delegate.sol b/contracts/modules/facets/IexecPoco2Facet.sol similarity index 99% rename from contracts/modules/delegates/IexecPoco2Delegate.sol rename to contracts/modules/facets/IexecPoco2Facet.sol index fa6447edf..22a5e7ca4 100644 --- a/contracts/modules/delegates/IexecPoco2Delegate.sol +++ b/contracts/modules/facets/IexecPoco2Facet.sol @@ -7,14 +7,14 @@ import {Math} from "@openzeppelin/contracts-v5/utils/math/Math.sol"; import {IOracleConsumer} from "../../external/interfaces/IOracleConsumer.sol"; import {IexecLibCore_v5} from "../../libs/IexecLibCore_v5.sol"; import {IexecLibOrders_v5} from "../../libs/IexecLibOrders_v5.sol"; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; import {IexecPoco2} from "../interfaces/IexecPoco2.v8.sol"; import {IexecEscrow} from "./IexecEscrow.v8.sol"; import {SignatureVerifier} from "./SignatureVerifier.v8.sol"; // TODO: Revert with custom errors -contract IexecPoco2Delegate is IexecPoco2, DelegateBase, IexecEscrow, SignatureVerifier { +contract IexecPoco2Facet is IexecPoco2, FacetBase, IexecEscrow, SignatureVerifier { modifier onlyScheduler(bytes32 _taskId) { require(_msgSender() == m_deals[m_tasks[_taskId].dealid].workerpool.owner); _; diff --git a/contracts/modules/delegates/IexecPocoAccessorsDelegate.sol b/contracts/modules/facets/IexecPocoAccessorsFacet.sol similarity index 92% rename from contracts/modules/delegates/IexecPocoAccessorsDelegate.sol rename to contracts/modules/facets/IexecPocoAccessorsFacet.sol index 1f871ab2b..fbc35dcb0 100644 --- a/contracts/modules/delegates/IexecPocoAccessorsDelegate.sol +++ b/contracts/modules/facets/IexecPocoAccessorsFacet.sol @@ -3,21 +3,21 @@ pragma solidity ^0.8.0; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; import {IexecLibCore_v5} from "../../libs/IexecLibCore_v5.sol"; import {IexecLibOrders_v5} from "../../libs/IexecLibOrders_v5.sol"; import {IexecPocoAccessors} from "../interfaces/IexecPocoAccessors.sol"; -import {IexecPocoCommonDelegate} from "./IexecPocoCommonDelegate.sol"; +import {IexecPocoCommonFacet} from "./IexecPocoCommonFacet.sol"; import {SignatureVerifier} from "./SignatureVerifier.v8.sol"; /** * @title Getters contract for PoCo module. */ -contract IexecPocoAccessorsDelegate is +contract IexecPocoAccessorsFacet is IexecPocoAccessors, - DelegateBase, + FacetBase, SignatureVerifier, - IexecPocoCommonDelegate + IexecPocoCommonFacet { using IexecLibOrders_v5 for IexecLibOrders_v5.AppOrder; using IexecLibOrders_v5 for IexecLibOrders_v5.DatasetOrder; diff --git a/contracts/modules/delegates/IexecPocoBoostAccessorsDelegate.sol b/contracts/modules/facets/IexecPocoBoostAccessorsFacet.sol similarity index 83% rename from contracts/modules/delegates/IexecPocoBoostAccessorsDelegate.sol rename to contracts/modules/facets/IexecPocoBoostAccessorsFacet.sol index fa3f47cbc..91136bf2c 100644 --- a/contracts/modules/delegates/IexecPocoBoostAccessorsDelegate.sol +++ b/contracts/modules/facets/IexecPocoBoostAccessorsFacet.sol @@ -4,14 +4,14 @@ pragma solidity ^0.8.0; import {IexecLibCore_v5} from "../../libs/IexecLibCore_v5.sol"; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; import {IexecPocoBoostAccessors} from "../interfaces/IexecPocoBoostAccessors.sol"; /** * @title Getters contract for PoCo Boost module. * @notice Access to PoCo Boost tasks must be done with PoCo Classic `IexecAccessors`. */ -contract IexecPocoBoostAccessorsDelegate is IexecPocoBoostAccessors, DelegateBase { +contract IexecPocoBoostAccessorsFacet is IexecPocoBoostAccessors, FacetBase { /** * Get a deal created by PoCo Boost module. * @param id The ID of the deal. diff --git a/contracts/modules/delegates/IexecPocoBoostDelegate.sol b/contracts/modules/facets/IexecPocoBoostFacet.sol similarity index 99% rename from contracts/modules/delegates/IexecPocoBoostDelegate.sol rename to contracts/modules/facets/IexecPocoBoostFacet.sol index 11cee8be1..37731fac3 100644 --- a/contracts/modules/delegates/IexecPocoBoostDelegate.sol +++ b/contracts/modules/facets/IexecPocoBoostFacet.sol @@ -13,22 +13,22 @@ import {IOracleConsumer} from "../../external/interfaces/IOracleConsumer.sol"; import {IexecLibCore_v5} from "../../libs/IexecLibCore_v5.sol"; import {IexecLibOrders_v5} from "../../libs/IexecLibOrders_v5.sol"; import {IWorkerpool} from "../../registries/workerpools/IWorkerpool.v8.sol"; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; import {IexecPocoBoost} from "../interfaces/IexecPocoBoost.sol"; import {IexecEscrow} from "./IexecEscrow.v8.sol"; -import {IexecPocoCommonDelegate} from "./IexecPocoCommonDelegate.sol"; +import {IexecPocoCommonFacet} from "./IexecPocoCommonFacet.sol"; import {SignatureVerifier} from "./SignatureVerifier.v8.sol"; /** * @title PoCo Boost to reduce latency and increase throughput of deals. * @notice Works for deals with requested trust = 0. */ -contract IexecPocoBoostDelegate is +contract IexecPocoBoostFacet is IexecPocoBoost, - DelegateBase, + FacetBase, IexecEscrow, SignatureVerifier, - IexecPocoCommonDelegate + IexecPocoCommonFacet { using ECDSA for bytes32; using MessageHashUtils for bytes32; diff --git a/contracts/modules/delegates/IexecPocoCommonDelegate.sol b/contracts/modules/facets/IexecPocoCommonFacet.sol similarity index 95% rename from contracts/modules/delegates/IexecPocoCommonDelegate.sol rename to contracts/modules/facets/IexecPocoCommonFacet.sol index 4f7eef766..9f55cc338 100644 --- a/contracts/modules/delegates/IexecPocoCommonDelegate.sol +++ b/contracts/modules/facets/IexecPocoCommonFacet.sol @@ -6,9 +6,9 @@ pragma solidity ^0.8.0; import {Math} from "@openzeppelin/contracts-v5/utils/math/Math.sol"; import {IexecLibOrders_v5} from "../../libs/IexecLibOrders_v5.sol"; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; -contract IexecPocoCommonDelegate is DelegateBase { +contract IexecPocoCommonFacet is FacetBase { using Math for uint256; using IexecLibOrders_v5 for IexecLibOrders_v5.AppOrder; using IexecLibOrders_v5 for IexecLibOrders_v5.DatasetOrder; diff --git a/contracts/modules/delegates/IexecRelayDelegate.sol b/contracts/modules/facets/IexecRelayFacet.sol similarity index 63% rename from contracts/modules/delegates/IexecRelayDelegate.sol rename to contracts/modules/facets/IexecRelayFacet.sol index 2f49797b4..39e2d5176 100644 --- a/contracts/modules/delegates/IexecRelayDelegate.sol +++ b/contracts/modules/facets/IexecRelayFacet.sol @@ -19,14 +19,26 @@ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; -import "../DelegateBase.sol"; +import "../FacetBase.sol"; import "../interfaces/IexecRelay.sol"; - -contract IexecRelayDelegate is IexecRelay, DelegateBase -{ - function broadcastAppOrder (IexecLibOrders_v5.AppOrder calldata _apporder ) external override { emit BroadcastAppOrder (_apporder ); } - function broadcastDatasetOrder (IexecLibOrders_v5.DatasetOrder calldata _datasetorder ) external override { emit BroadcastDatasetOrder (_datasetorder ); } - function broadcastWorkerpoolOrder(IexecLibOrders_v5.WorkerpoolOrder calldata _workerpoolorder) external override { emit BroadcastWorkerpoolOrder(_workerpoolorder); } - function broadcastRequestOrder (IexecLibOrders_v5.RequestOrder calldata _requestorder ) external override { emit BroadcastRequestOrder (_requestorder ); } +contract IexecRelayFacet is IexecRelay, FacetBase { + function broadcastAppOrder(IexecLibOrders_v5.AppOrder calldata _apporder) external override { + emit BroadcastAppOrder(_apporder); + } + function broadcastDatasetOrder( + IexecLibOrders_v5.DatasetOrder calldata _datasetorder + ) external override { + emit BroadcastDatasetOrder(_datasetorder); + } + function broadcastWorkerpoolOrder( + IexecLibOrders_v5.WorkerpoolOrder calldata _workerpoolorder + ) external override { + emit BroadcastWorkerpoolOrder(_workerpoolorder); + } + function broadcastRequestOrder( + IexecLibOrders_v5.RequestOrder calldata _requestorder + ) external override { + emit BroadcastRequestOrder(_requestorder); + } } diff --git a/contracts/modules/facets/SignatureVerifier.sol b/contracts/modules/facets/SignatureVerifier.sol new file mode 100644 index 000000000..79eef1f34 --- /dev/null +++ b/contracts/modules/facets/SignatureVerifier.sol @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: Apache-2.0 + +/****************************************************************************** + * Copyright 2020 IEXEC BLOCKCHAIN TECH * + * * + * Licensed under the Apache License, Version 2.0 (the "License"); * + * you may not use this file except in compliance with the License. * + * You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, software * + * distributed under the License is distributed on an "AS IS" BASIS, * + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * + * See the License for the specific language governing permissions and * + * limitations under the License. * + ******************************************************************************/ + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "@iexec/solidity/contracts/ERC734/IERC734.sol"; +import "@iexec/solidity/contracts/ERC1271/IERC1271.sol"; +import "@iexec/solidity/contracts/ERC1654/IERC1654.sol"; +import "../FacetBase.sol"; + +contract SignatureVerifier is FacetBase { + /** + * Prepare message/structure predicat used for signing + */ + function _toEthSignedMessage(bytes32 _msgHash) internal pure returns (bytes memory) { + return abi.encodePacked("\x19Ethereum Signed Message:\n32", _msgHash); + } + + function _toEthTypedStruct( + bytes32 _structHash, + bytes32 _domainHash + ) internal pure returns (bytes memory) { + return abi.encodePacked("\x19\x01", _domainHash, _structHash); + } + + /** + * recover EOA signature (support both 65 bytes traditional and 64 bytes format EIP2098 format) + */ + function _recover(bytes32 _hash, bytes memory _sign) internal pure returns (address) { + bytes32 r; + bytes32 s; + uint8 v; + + if (_sign.length == 65) // 65bytes: (r,s,v) form + { + assembly { + r := mload(add(_sign, 0x20)) + s := mload(add(_sign, 0x40)) + v := byte(0, mload(add(_sign, 0x60))) + } + } else if (_sign.length == 64) // 64bytes: (r,vs) form → see EIP2098 + { + assembly { + r := mload(add(_sign, 0x20)) + s := and( + mload(add(_sign, 0x40)), + 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + ) + v := shr(7, byte(0, mload(add(_sign, 0x40)))) + } + } else { + revert("invalid-signature-format"); + } + + if (v < 27) v += 27; + require(v == 27 || v == 28, "invalid-signature-v"); + return ecrecover(_hash, v, r, s); + } + + /** + * Check if contract exist, otherwize assumed to be EOA + */ + function _isContract(address account) internal view returns (bool) { + // According to EIP-1052, 0x0 is the value returned for not-yet created accounts + // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned + // for accounts without code, i.e. `keccak256('')` + bytes32 codehash; + bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + // solhint-disable-next-line no-inline-assembly + assembly { + codehash := extcodehash(account) + } + return (codehash != accountHash && codehash != 0x0); + } + + /** + * Address to bytes32 casting to ERC734 + */ + function _addrToKey(address _addr) internal pure returns (bytes32) { + return bytes32(uint256(_addr)); + } + + /** + * Identity verification + */ + function _checkIdentity( + address _identity, + address _candidate, + uint256 _purpose + ) internal view returns (bool valid) { + return + _identity == _candidate || + IERC734(_identity).keyHasPurpose(_addrToKey(_candidate), _purpose); // Simple address || ERC 734 identity contract + } + + function _checkPresignature(address _identity, bytes32 _hash) internal view returns (bool) { + return _identity != address(0) && _identity == m_presigned[_hash]; + } + + function _checkSignature( + address _identity, + bytes32 _hash, + bytes memory _signature + ) internal view returns (bool) { + if (_isContract(_identity)) { + try IERC1654(_identity).isValidSignature(_hash, _signature) returns (bytes4 value) { + return value == IERC1654(0).isValidSignature.selector; + } catch (bytes memory /*lowLevelData*/) {} + + return false; + } else { + return _recover(_hash, _signature) == _identity; + } + } + + function _checkSignature( + address _identity, + bytes memory _predicat, + bytes memory _signature + ) internal view returns (bool) { + if (_isContract(_identity)) { + try IERC1271(_identity).isValidSignature(_predicat, _signature) returns (bytes4 value) { + return value == IERC1271(0).isValidSignature.selector; + } catch (bytes memory /*lowLevelData*/) {} + + try IERC1654(_identity).isValidSignature(keccak256(_predicat), _signature) returns ( + bytes4 value + ) { + return value == IERC1654(0).isValidSignature.selector; + } catch (bytes memory /*lowLevelData*/) {} + + return false; + } else { + return _recover(keccak256(_predicat), _signature) == _identity; + } + } + + function _checkPresignatureOrSignature( + address _identity, + bytes32 _hash, + bytes memory _signature + ) internal view returns (bool) { + return + _checkPresignature(_identity, _hash) || _checkSignature(_identity, _hash, _signature); + } + + function _checkPresignatureOrSignature( + address _identity, + bytes memory _predicat, + bytes memory _signature + ) internal view returns (bool) { + return + _checkPresignature(_identity, keccak256(_predicat)) || + _checkSignature(_identity, _predicat, _signature); + } +} diff --git a/contracts/modules/delegates/SignatureVerifier.v8.sol b/contracts/modules/facets/SignatureVerifier.v8.sol similarity index 98% rename from contracts/modules/delegates/SignatureVerifier.v8.sol rename to contracts/modules/facets/SignatureVerifier.v8.sol index bf91b909b..c537f280a 100644 --- a/contracts/modules/delegates/SignatureVerifier.v8.sol +++ b/contracts/modules/facets/SignatureVerifier.v8.sol @@ -7,9 +7,9 @@ import {IERC1271} from "@openzeppelin/contracts-v5/interfaces/IERC1271.sol"; import {ECDSA} from "@openzeppelin/contracts-v5/utils/cryptography/ECDSA.sol"; import {MessageHashUtils} from "@openzeppelin/contracts-v5/utils/cryptography/MessageHashUtils.sol"; import {IERC734} from "../../external/interfaces/IERC734.sol"; -import {DelegateBase} from "../DelegateBase.v8.sol"; +import {FacetBase} from "../FacetBase.v8.sol"; -contract SignatureVerifier is DelegateBase { +contract SignatureVerifier is FacetBase { using ECDSA for bytes32; /** diff --git a/contracts/tools/testing/IexecEscrowTestContract.sol b/contracts/tools/testing/IexecEscrowTestContract.sol index 58098036f..34f59e25f 100644 --- a/contracts/tools/testing/IexecEscrowTestContract.sol +++ b/contracts/tools/testing/IexecEscrowTestContract.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.0; -import {IexecEscrow} from "../../modules/delegates/IexecEscrow.v8.sol"; +import {IexecEscrow} from "../../modules/facets/IexecEscrow.v8.sol"; /** * @notice a wrapper contract to make internal functions of diff --git a/contracts/tools/testing/IexecPocoBoostCompositeDelegate.sol b/contracts/tools/testing/IexecPocoBoostCompositeDelegate.sol index 4b465850d..a675d74ac 100644 --- a/contracts/tools/testing/IexecPocoBoostCompositeDelegate.sol +++ b/contracts/tools/testing/IexecPocoBoostCompositeDelegate.sol @@ -3,15 +3,15 @@ pragma solidity ^0.8.0; -import {IexecPocoAccessorsDelegate} from "../../modules/delegates/IexecPocoAccessorsDelegate.sol"; -import {IexecPocoBoostAccessorsDelegate} from "../../modules/delegates/IexecPocoBoostAccessorsDelegate.sol"; -import {IexecPocoBoostDelegate} from "../../modules/delegates/IexecPocoBoostDelegate.sol"; +import {IexecPocoAccessorsFacet} from "../../modules/facets/IexecPocoAccessorsFacet.sol"; +import {IexecPocoBoostAccessorsFacet} from "../../modules/facets/IexecPocoBoostAccessorsFacet.sol"; +import {IexecPocoBoostFacet} from "../../modules/facets/IexecPocoBoostFacet.sol"; /** * @notice This contract is dedicated to unit testing. */ -contract IexecPocoBoostCompositeDelegate is - IexecPocoAccessorsDelegate, - IexecPocoBoostAccessorsDelegate, - IexecPocoBoostDelegate +contract IexecPocoBoostCompositeFacet is + IexecPocoAccessorsFacet, + IexecPocoBoostAccessorsFacet, + IexecPocoBoostFacet {} diff --git a/contracts/tools/testing/IexecPocoBoostCompositeFacet.sol b/contracts/tools/testing/IexecPocoBoostCompositeFacet.sol new file mode 100644 index 000000000..a675d74ac --- /dev/null +++ b/contracts/tools/testing/IexecPocoBoostCompositeFacet.sol @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2023 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.8.0; + +import {IexecPocoAccessorsFacet} from "../../modules/facets/IexecPocoAccessorsFacet.sol"; +import {IexecPocoBoostAccessorsFacet} from "../../modules/facets/IexecPocoBoostAccessorsFacet.sol"; +import {IexecPocoBoostFacet} from "../../modules/facets/IexecPocoBoostFacet.sol"; + +/** + * @notice This contract is dedicated to unit testing. + */ +contract IexecPocoBoostCompositeFacet is + IexecPocoAccessorsFacet, + IexecPocoBoostAccessorsFacet, + IexecPocoBoostFacet +{} diff --git a/contracts/tools/testing/slither/Slither.sol b/contracts/tools/testing/slither/Slither.sol index 18f086949..b835e3574 100644 --- a/contracts/tools/testing/slither/Slither.sol +++ b/contracts/tools/testing/slither/Slither.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.0; -import {IexecPocoAccessorsDelegate} from "../../../modules/delegates/IexecPocoAccessorsDelegate.sol"; -import {IexecPoco1Delegate} from "../../../modules/delegates/IexecPoco1Delegate.sol"; -import {IexecPoco2Delegate} from "../../../modules/delegates/IexecPoco2Delegate.sol"; +import {IexecPocoAccessorsFacet} from "../../../modules/facets/IexecPocoAccessorsFacet.sol"; +import {IexecPoco1Facet} from "../../../modules/facets/IexecPoco1Facet.sol"; +import {IexecPoco2Facet} from "../../../modules/facets/IexecPoco2Facet.sol"; /** * @notice This contract is dedicated to slither analysis. @@ -14,5 +14,5 @@ import {IexecPoco2Delegate} from "../../../modules/delegates/IexecPoco2Delegate. * to facilitate static analysis using Slither. */ //slither-disable-start unused-state -contract Slither is IexecPocoAccessorsDelegate, IexecPoco1Delegate, IexecPoco2Delegate {} +contract Slither is IexecPocoAccessorsFacet, IexecPoco1Facet, IexecPoco2Facet {} //slither-disable-end unused-state diff --git a/contracts/tools/testing/slither/SlitherBoost.sol b/contracts/tools/testing/slither/SlitherBoost.sol index 94b466937..048945ad8 100644 --- a/contracts/tools/testing/slither/SlitherBoost.sol +++ b/contracts/tools/testing/slither/SlitherBoost.sol @@ -3,8 +3,8 @@ pragma solidity ^0.8.0; -import {IexecPocoBoostAccessorsDelegate} from "../../../modules/delegates/IexecPocoBoostAccessorsDelegate.sol"; -import {IexecPocoBoostDelegate} from "../../../modules/delegates/IexecPocoBoostDelegate.sol"; +import {IexecPocoBoostAccessorsFacet} from "../../../modules/facets/IexecPocoBoostAccessorsFacet.sol"; +import {IexecPocoBoostFacet} from "../../../modules/facets/IexecPocoBoostFacet.sol"; /** * @notice This contract is dedicated to slither analysis. @@ -13,5 +13,5 @@ import {IexecPocoBoostDelegate} from "../../../modules/delegates/IexecPocoBoostD * to facilitate static analysis using Slither. */ //slither-disable-start unused-state -contract SlitherBoost is IexecPocoBoostDelegate, IexecPocoBoostAccessorsDelegate {} +contract SlitherBoost is IexecPocoBoostFacet, IexecPocoBoostAccessorsFacet {} //slither-disable-end unused-state diff --git a/hardhat.config.ts b/hardhat.config.ts index c82fbf221..c2e63676c 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -272,10 +272,10 @@ const config: HardhatUserConfig = { templates: 'docs/solidity/templates', exclude: [ 'external', - 'modules/delegates/IexecAccessorsABILegacyDelegate.sol', // not relevant - 'modules/delegates/IexecEscrowTokenSwapDelegate.sol', // not relevant - 'modules/delegates/SignatureVerifier.sol', // contains only internal/private - 'modules/delegates/SignatureVerifier.v8.sol', + 'modules/facets/IexecAccessorsABILegacyFacet.sol', // not relevant + 'modules/facets/IexecEscrowTokenSwapFacet.sol', // not relevant + 'modules/facets/SignatureVerifier.sol', // contains only internal/private + 'modules/facets/SignatureVerifier.v8.sol', 'modules/interfaces', // interesting for events but too much doc duplication if enabled 'registries', // ignore them for now 'tools', From a0b4200ecf5bbc29b8cdd47dfc35fa2fccaa4638 Mon Sep 17 00:00:00 2001 From: gfournieriExec Date: Fri, 25 Jul 2025 17:30:05 +0200 Subject: [PATCH 2/6] feat: Update contract references from delegate to facet naming across multiple files --- .../tools/testing/IexecEscrowTestContract.sol | 2 +- deploy/0_deploy.ts | 64 +++++++++---------- scripts/boost/0_deploy-modules.ts | 12 ++-- scripts/boost/1_add-modules-to-proxy.ts | 10 +-- scripts/set-callback-gas.ts | 4 +- scripts/sponsoring/0_deploy-modules.ts | 24 +++---- scripts/sponsoring/1_add-modules-to-proxy.ts | 33 +++++----- test/000_fullchain-boost.test.ts | 12 ++-- .../IexecPocoBoost/IexecPocoBoost.test.ts | 12 ++-- test/utils/IexecWrapper.ts | 6 +- 10 files changed, 88 insertions(+), 91 deletions(-) diff --git a/contracts/tools/testing/IexecEscrowTestContract.sol b/contracts/tools/testing/IexecEscrowTestContract.sol index 34f59e25f..9d961f0ef 100644 --- a/contracts/tools/testing/IexecEscrowTestContract.sol +++ b/contracts/tools/testing/IexecEscrowTestContract.sol @@ -32,7 +32,7 @@ contract IexecEscrowTestContract is IexecEscrow { m_balances[account] = value; } - // TODO remove the following function and inherit `IexecAccessorsDelegate` + // TODO remove the following function and inherit `IexecAccessorsFacet` // when it is migrated to solidity v8. function balanceOf(address account) external view returns (uint256) { diff --git a/deploy/0_deploy.ts b/deploy/0_deploy.ts index 5798178b3..7bf2e5e5b 100644 --- a/deploy/0_deploy.ts +++ b/deploy/0_deploy.ts @@ -13,29 +13,29 @@ import { DiamondLoupeFacet, DiamondLoupeFacet__factory, Diamond__factory, - IexecAccessorsABILegacyDelegate__factory, - IexecAccessorsDelegate__factory, + IexecAccessorsABILegacyFacet__factory, + IexecAccessorsFacet__factory, IexecAccessors__factory, - IexecCategoryManagerDelegate__factory, + IexecCategoryManagerFacet__factory, IexecCategoryManager__factory, - IexecERC20Delegate__factory, - IexecEscrowNativeDelegate__factory, - IexecEscrowTokenDelegate__factory, + IexecERC20Facet__factory, + IexecEscrowNativeFacet__factory, + IexecEscrowTokenFacet__factory, IexecLibOrders_v5__factory, - IexecMaintenanceDelegate__factory, - IexecMaintenanceExtraDelegate__factory, - IexecOrderManagementDelegate__factory, - IexecPoco1Delegate__factory, - IexecPoco2Delegate__factory, - IexecPocoAccessorsDelegate__factory, - IexecPocoBoostAccessorsDelegate__factory, - IexecPocoBoostDelegate__factory, - IexecRelayDelegate__factory, + IexecMaintenanceExtraFacet__factory, + IexecMaintenanceFacet__factory, + IexecOrderManagementFacet__factory, + IexecPoco1Facet__factory, + IexecPoco2Facet__factory, + IexecPocoAccessorsFacet__factory, + IexecPocoBoostAccessorsFacet__factory, + IexecPocoBoostFacet__factory, + IexecRelayFacet__factory, OwnershipFacet__factory, RLC__factory, WorkerpoolRegistry__factory, } from '../typechain'; -import { DiamondArgsStruct } from '../typechain/@mudgen/diamond-1/contracts/Diamond'; +import { DiamondArgsStruct } from '../typechain/contracts/Diamond'; import { Ownable__factory } from '../typechain/factories/@openzeppelin/contracts/access'; import { FactoryDeployer } from '../utils/FactoryDeployer'; import config from '../utils/config'; @@ -84,22 +84,20 @@ export default async function deploy() { ['contracts/libs/IexecLibOrders_v5.sol:IexecLibOrders_v5']: iexecLibOrdersAddress, }; const modules = [ - new IexecAccessorsDelegate__factory(), - new IexecAccessorsABILegacyDelegate__factory(), - new IexecCategoryManagerDelegate__factory(), - new IexecERC20Delegate__factory(), - isTokenMode - ? new IexecEscrowTokenDelegate__factory() - : new IexecEscrowNativeDelegate__factory(), - new IexecMaintenanceDelegate__factory(iexecLibOrders), - new IexecOrderManagementDelegate__factory(iexecLibOrders), - new IexecPoco1Delegate__factory(iexecLibOrders), - new IexecPoco2Delegate__factory(), - new IexecRelayDelegate__factory(), - new IexecMaintenanceExtraDelegate__factory(), - new IexecPocoAccessorsDelegate__factory(iexecLibOrders), - new IexecPocoBoostDelegate__factory(iexecLibOrders), - new IexecPocoBoostAccessorsDelegate__factory(), + new IexecAccessorsFacet__factory(), + new IexecAccessorsABILegacyFacet__factory(), + new IexecCategoryManagerFacet__factory(), + new IexecERC20Facet__factory(), + isTokenMode ? new IexecEscrowTokenFacet__factory() : new IexecEscrowNativeFacet__factory(), + new IexecMaintenanceFacet__factory(iexecLibOrders), + new IexecOrderManagementFacet__factory(iexecLibOrders), + new IexecPoco1Facet__factory(iexecLibOrders), + new IexecPoco2Facet__factory(), + new IexecRelayFacet__factory(), + new IexecMaintenanceExtraFacet__factory(), + new IexecPocoAccessorsFacet__factory(iexecLibOrders), + new IexecPocoBoostFacet__factory(iexecLibOrders), + new IexecPocoBoostAccessorsFacet__factory(), ]; for (const module of modules) { const address = await factoryDeployer.deployContract(module); @@ -178,7 +176,7 @@ export default async function deploy() { const iexecInitialized = (await iexecAccessorsInstance.eip712domain_separator()) != ZeroHash; if (!iexecInitialized) { // TODO replace this with DiamondInit.init(). - await IexecMaintenanceDelegate__factory.connect(diamondProxyAddress, owner) + await IexecMaintenanceFacet__factory.connect(diamondProxyAddress, owner) .configure( rlcInstanceAddress, 'Staked RLC', diff --git a/scripts/boost/0_deploy-modules.ts b/scripts/boost/0_deploy-modules.ts index 5be989281..32779dd63 100644 --- a/scripts/boost/0_deploy-modules.ts +++ b/scripts/boost/0_deploy-modules.ts @@ -4,8 +4,8 @@ import { deployments, ethers } from 'hardhat'; import { GenericFactory__factory, - IexecPocoBoostAccessorsDelegate__factory, - IexecPocoBoostDelegate__factory, + IexecPocoBoostAccessorsFacet__factory, + IexecPocoBoostFacet__factory, } from '../../typechain'; import config from '../../utils/config'; import { mineBlockIfOnLocalFork } from '../../utils/mine'; @@ -23,15 +23,15 @@ const genericFactoryAddress = require('@amxx/factory/deployments/GenericFactory. const salt = deploymentOptions.salt; const modules = [ { - name: 'IexecPocoBoostDelegate', - bytecode: IexecPocoBoostDelegate__factory.linkBytecode({ + name: 'IexecPocoBoostFacet', + bytecode: IexecPocoBoostFacet__factory.linkBytecode({ ['contracts/libs/IexecLibOrders_v5.sol:IexecLibOrders_v5']: deploymentOptions.IexecLibOrders_v5, }), }, { - name: 'IexecPocoBoostAccessorsDelegate', - bytecode: IexecPocoBoostAccessorsDelegate__factory.bytecode, + name: 'IexecPocoBoostAccessorsFacet', + bytecode: IexecPocoBoostAccessorsFacet__factory.bytecode, }, ]; const genericFactoryInstance = GenericFactory__factory.connect(genericFactoryAddress, owner); diff --git a/scripts/boost/1_add-modules-to-proxy.ts b/scripts/boost/1_add-modules-to-proxy.ts index ff3734354..5c0af845a 100644 --- a/scripts/boost/1_add-modules-to-proxy.ts +++ b/scripts/boost/1_add-modules-to-proxy.ts @@ -25,19 +25,19 @@ import { throw new Error('DiamondProxy is required'); } const diamondProxyAddress = deploymentOptions.DiamondProxy; - const iexecPocoBoostDelegateAddress = (await deployments.get('IexecPocoBoostDelegate')).address; // Bellecour: 0x8425229f979AB3b0dDDe00D475D762cA4d6a5eFc - const iexecPocoBoostAccessorsDelegateAddress = ( - await deployments.get('IexecPocoBoostAccessorsDelegate') + const iexecPocoBoostFacetAddress = (await deployments.get('IexecPocoBoostFacet')).address; // Bellecour: 0x8425229f979AB3b0dDDe00D475D762cA4d6a5eFc + const iexecPocoBoostAccessorsFacetAddress = ( + await deployments.get('IexecPocoBoostAccessorsFacet') ).address; // Bellecour: 0x56185a2b0dc8b556BBfBAFB702BC971Ed75e868C const [account] = await ethers.getSigners(); const timelockAddress = await Ownable__factory.connect(diamondProxyAddress, account).owner(); // Bellecour: 0x4611B943AA1d656Fc669623b5DA08756A7e288E9 const iexecPocoBoostProxyUpdate = encodeModuleProxyUpdate( IexecPocoBoost__factory.createInterface(), - iexecPocoBoostDelegateAddress, + iexecPocoBoostFacetAddress, ); const iexecPocoBoostAccessorsProxyUpdate = encodeModuleProxyUpdate( IexecPocoBoostAccessors__factory.createInterface(), - iexecPocoBoostAccessorsDelegateAddress, + iexecPocoBoostAccessorsFacetAddress, ); // Salt but must be the same for schedule & execute const operationSalt = '0x0be814a62c44af32241a2c964e5680d1b25c783473c6e7875cbc8071770d7ff0'; // Random diff --git a/scripts/set-callback-gas.ts b/scripts/set-callback-gas.ts index e15a28e73..86610387a 100644 --- a/scripts/set-callback-gas.ts +++ b/scripts/set-callback-gas.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { deployments, ethers } from 'hardhat'; -import { IexecAccessors__factory, IexecMaintenanceDelegate__factory } from '../typechain'; +import { IexecAccessors__factory, IexecMaintenanceFacet__factory } from '../typechain'; (async () => { const requestedCallbackGas = Number(process.env.CALLBACK_GAS); @@ -18,7 +18,7 @@ import { IexecAccessors__factory, IexecMaintenanceDelegate__factory } from '../t .toNumber() .toLocaleString(); const callbackGasBefore = await viewCallbackGas(); - await IexecMaintenanceDelegate__factory.connect(diamondProxyAddress, owner) + await IexecMaintenanceFacet__factory.connect(diamondProxyAddress, owner) .setCallbackGas(requestedCallbackGas) .then((tx) => tx.wait()); console.log(`Changed callback-gas from ${callbackGasBefore} to ${await viewCallbackGas()}`); diff --git a/scripts/sponsoring/0_deploy-modules.ts b/scripts/sponsoring/0_deploy-modules.ts index d4d490c38..d195eb95b 100644 --- a/scripts/sponsoring/0_deploy-modules.ts +++ b/scripts/sponsoring/0_deploy-modules.ts @@ -4,10 +4,10 @@ import { deployments, ethers } from 'hardhat'; import { GenericFactory__factory, - IexecOrderManagementDelegate__factory, - IexecPoco1Delegate__factory, - IexecPoco2Delegate__factory, - IexecPocoAccessorsDelegate__factory, + IexecOrderManagementFacet__factory, + IexecPoco1Facet__factory, + IexecPoco2Facet__factory, + IexecPocoAccessorsFacet__factory, } from '../../typechain'; import config from '../../utils/config'; const genericFactoryAddress = require('@amxx/factory/deployments/GenericFactory.json').address; @@ -34,20 +34,20 @@ export async function deployModules() { }; const modules = [ { - name: 'IexecOrderManagementDelegate', - contract: new IexecOrderManagementDelegate__factory(libraries), + name: 'IexecOrderManagementFacet', + contract: new IexecOrderManagementFacet__factory(libraries), }, { - name: 'IexecPoco1Delegate', - contract: new IexecPoco1Delegate__factory(libraries), + name: 'IexecPoco1Facet', + contract: new IexecPoco1Facet__factory(libraries), }, { - name: 'IexecPoco2Delegate', - contract: new IexecPoco2Delegate__factory(), + name: 'IexecPoco2Facet', + contract: new IexecPoco2Facet__factory(), }, { - name: 'IexecPocoAccessorsDelegate', - contract: new IexecPocoAccessorsDelegate__factory(libraries), + name: 'IexecPocoAccessorsFacet', + contract: new IexecPocoAccessorsFacet__factory(libraries), }, ]; const genericFactoryInstance = GenericFactory__factory.connect(genericFactoryAddress, deployer); diff --git a/scripts/sponsoring/1_add-modules-to-proxy.ts b/scripts/sponsoring/1_add-modules-to-proxy.ts index 04f01a2cc..e18cec849 100644 --- a/scripts/sponsoring/1_add-modules-to-proxy.ts +++ b/scripts/sponsoring/1_add-modules-to-proxy.ts @@ -5,10 +5,10 @@ import { time } from '@nomicfoundation/hardhat-network-helpers'; import { BytesLike, ZeroHash } from 'ethers'; import hre, { ethers } from 'hardhat'; import { - IexecOrderManagementDelegate__factory, - IexecPoco1Delegate__factory, - IexecPoco2Delegate__factory, - IexecPocoAccessorsDelegate__factory, + IexecOrderManagementFacet__factory, + IexecPoco1Facet__factory, + IexecPoco2Facet__factory, + IexecPocoAccessorsFacet__factory, Ownable__factory, TimelockController__factory, } from '../../typechain'; @@ -33,13 +33,12 @@ export async function addModulesToProxy() { throw new Error('DiamondProxy is required'); } const diamondProxyAddress = deploymentOptions.DiamondProxy; - const iexecOrderManagementAddress = (await hre.deployments.get('IexecOrderManagementDelegate')) + const iexecOrderManagementAddress = (await hre.deployments.get('IexecOrderManagementFacet')) + .address; + const iexecPoco1FacetAddress = (await hre.deployments.get('IexecPoco1Facet')).address; + const iexecPoco2FacetAddress = (await hre.deployments.get('IexecPoco2Facet')).address; + const iexecPocoAccessorsFacetAddress = (await hre.deployments.get('IexecPocoAccessorsFacet')) .address; - const iexecPoco1DelegateAddress = (await hre.deployments.get('IexecPoco1Delegate')).address; - const iexecPoco2DelegateAddress = (await hre.deployments.get('IexecPoco2Delegate')).address; - const iexecPocoAccessorsDelegateAddress = ( - await hre.deployments.get('IexecPocoAccessorsDelegate') - ).address; await printFunctions(diamondProxyAddress); console.log('Functions about to be added to proxy:'); @@ -48,20 +47,20 @@ export async function addModulesToProxy() { ethers.provider, ).owner(); const iexecOrderManagementProxyUpdate = encodeModuleProxyUpdate( - IexecOrderManagementDelegate__factory.createInterface(), + IexecOrderManagementFacet__factory.createInterface(), iexecOrderManagementAddress, ); const iexecPoco1ProxyUpdate = encodeModuleProxyUpdate( - IexecPoco1Delegate__factory.createInterface(), - iexecPoco1DelegateAddress, + IexecPoco1Facet__factory.createInterface(), + iexecPoco1FacetAddress, ); const iexecPoco2ProxyUpdate = encodeModuleProxyUpdate( - IexecPoco2Delegate__factory.createInterface(), - iexecPoco2DelegateAddress, + IexecPoco2Facet__factory.createInterface(), + iexecPoco2FacetAddress, ); const iexecPocoAccessorsProxyUpdate = encodeModuleProxyUpdate( - IexecPocoAccessorsDelegate__factory.createInterface(), - iexecPocoAccessorsDelegateAddress, + IexecPocoAccessorsFacet__factory.createInterface(), + iexecPocoAccessorsFacetAddress, ); // The salt must be the same for a given schedule & execute operation set // Please increment salt in case of operation ID collision diff --git a/test/000_fullchain-boost.test.ts b/test/000_fullchain-boost.test.ts index 14fce3fcb..e22218d82 100644 --- a/test/000_fullchain-boost.test.ts +++ b/test/000_fullchain-boost.test.ts @@ -10,9 +10,9 @@ import { IexecAccessors, IexecAccessors__factory, IexecOrderManagement__factory, - IexecPocoBoostAccessorsDelegate__factory, - IexecPocoBoostDelegate, - IexecPocoBoostDelegate__factory, + IexecPocoBoostAccessorsFacet__factory, + IexecPocoBoostFacet, + IexecPocoBoostFacet__factory, TestClient__factory, WorkerpoolInterface__factory, } from '../typechain'; @@ -50,7 +50,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { let domain: TypedDataDomain; let proxyAddress: string; let iexecInstance: IexecAccessors; - let iexecPocoBoostInstance: IexecPocoBoostDelegate; + let iexecPocoBoostInstance: IexecPocoBoostFacet; let iexecWrapper: IexecWrapper; let appAddress = ''; let workerpoolAddress = ''; @@ -86,7 +86,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { workerpoolOwner: scheduler, requester: requester, }; - iexecPocoBoostInstance = IexecPocoBoostDelegate__factory.connect(proxyAddress, owner); + iexecPocoBoostInstance = IexecPocoBoostFacet__factory.connect(proxyAddress, owner); iexecInstance = IexecAccessors__factory.connect(proxyAddress, anyone); domain = { name: 'iExecODB', @@ -773,7 +773,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { }); async function viewDealBoost(dealId: string) { - return await IexecPocoBoostAccessorsDelegate__factory.connect( + return await IexecPocoBoostAccessorsFacet__factory.connect( proxyAddress, anyone, ).viewDealBoost(dealId); diff --git a/test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts b/test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts index 1e7a6fcde..bbfb6e763 100644 --- a/test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts +++ b/test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts @@ -21,9 +21,9 @@ import { IexecOrderManagement__factory, IexecPoco2__factory, IexecPocoAccessors__factory, - IexecPocoBoostAccessorsDelegate__factory, - IexecPocoBoostDelegate, - IexecPocoBoostDelegate__factory, + IexecPocoBoostAccessorsFacet__factory, + IexecPocoBoostFacet, + IexecPocoBoostFacet__factory, OwnableMock__factory, TestClient, TestClient__factory, @@ -72,7 +72,7 @@ const someSignature = '0xabcd'; // contract signatures could have arbitrary form const randomEOAAddress = ethers.Wallet.createRandom().address; let proxyAddress: string; -let iexecPocoBoostInstance: IexecPocoBoostDelegate; +let iexecPocoBoostInstance: IexecPocoBoostFacet; let iexecMaintenanceAsAdmin: IexecMaintenance; let iexecAccessor: IexecAccessors; let oracleConsumerInstance: TestClient; @@ -124,7 +124,7 @@ describe('IexecPocoBoost', function () { iexecWrapper = new IexecWrapper(proxyAddress, accounts); domain = iexecWrapper.getDomain(); ({ appAddress, datasetAddress, workerpoolAddress } = await iexecWrapper.createAssets()); - iexecPocoBoostInstance = IexecPocoBoostDelegate__factory.connect(proxyAddress, anyone); + iexecPocoBoostInstance = IexecPocoBoostFacet__factory.connect(proxyAddress, anyone); iexecMaintenanceAsAdmin = IexecMaintenance__factory.connect( proxyAddress, accounts.iexecAdmin, @@ -2442,7 +2442,7 @@ async function expectFrozen(account: string, expectedFrozenValue: bigint) { } async function viewDealBoost(dealId: string) { - return await IexecPocoBoostAccessorsDelegate__factory.connect( + return await IexecPocoBoostAccessorsFacet__factory.connect( proxyAddress, ethers.provider, ).viewDealBoost(dealId); diff --git a/test/utils/IexecWrapper.ts b/test/utils/IexecWrapper.ts index 537e531ed..63843cda5 100644 --- a/test/utils/IexecWrapper.ts +++ b/test/utils/IexecWrapper.ts @@ -21,7 +21,7 @@ import { IexecAccessors__factory, IexecInterfaceNative__factory, IexecLibOrders_v5, - IexecMaintenanceDelegate__factory, + IexecMaintenanceFacet__factory, IexecPoco2__factory, IexecPocoAccessors__factory, IexecPocoBoostAccessors__factory, @@ -33,6 +33,7 @@ import { } from '../../typechain'; import { TransferEvent } from '../../typechain/contracts/registries/IRegistry'; import { IexecPoco1__factory } from '../../typechain/factories/contracts/modules/interfaces/IexecPoco1.v8.sol/IexecPoco1__factory'; +import config from '../../utils/config'; import { IexecOrders, OrderOperation, @@ -50,7 +51,6 @@ import { getTaskId, setNextBlockTimestamp, } from '../../utils/poco-tools'; -import config from '../../utils/config'; export class IexecWrapper { proxyAddress: string; @@ -176,7 +176,7 @@ export class IexecWrapper { } async setTeeBroker(brokerAddress: string) { - await IexecMaintenanceDelegate__factory.connect(this.proxyAddress, this.accounts.iexecAdmin) + await IexecMaintenanceFacet__factory.connect(this.proxyAddress, this.accounts.iexecAdmin) .setTeeBroker(brokerAddress) .then((tx) => tx.wait()); } From 02febd3eddd6a1a15def5c6a4a12d1c39d271cbc Mon Sep 17 00:00:00 2001 From: gfournieriExec Date: Fri, 25 Jul 2025 17:32:54 +0200 Subject: [PATCH 3/6] feat: Remove DelegateBase and DelegateBase.v8 contracts --- contracts/modules/DelegateBase.sol | 26 ---------------------- contracts/modules/DelegateBase.v8.sol | 31 --------------------------- 2 files changed, 57 deletions(-) delete mode 100644 contracts/modules/DelegateBase.sol delete mode 100644 contracts/modules/DelegateBase.v8.sol diff --git a/contracts/modules/DelegateBase.sol b/contracts/modules/DelegateBase.sol deleted file mode 100644 index 56e3c7535..000000000 --- a/contracts/modules/DelegateBase.sol +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: 2020-2024 IEXEC BLOCKCHAIN TECH -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.6.0; - -import "../Store.sol"; -import "./interfaces/IOwnable.sol"; - -// Functions that were declared in ERC1538Store are re-declared here. -// TODO clean this (use LibDiamond) -// - All calls to `owner()` should use `LibDiamond.contractOwner()`. - -abstract contract FacetBase is Store { - modifier onlyOwner() { - require(_msgSender() == owner(), "Ownable: caller is not the owner"); - _; - } - - function owner() public view returns (address) { - return IOwnable(address(this)).owner(); - } - - function _msgSender() internal view returns (address) { - return msg.sender; - } -} diff --git a/contracts/modules/DelegateBase.v8.sol b/contracts/modules/DelegateBase.v8.sol deleted file mode 100644 index 23b43b5d9..000000000 --- a/contracts/modules/DelegateBase.v8.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2023 IEXEC BLOCKCHAIN TECH -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.8.0; - -import {IERC5313} from "@openzeppelin/contracts-v5/interfaces/IERC5313.sol"; -import {Store} from "../Store.v8.sol"; - -// Functions that were declared in ERC1538Store are re-declared here. -// TODO clean this (use LibDiamond) -// - All calls to `owner()` should use `LibDiamond.contractOwner()`. - -/** - * @title Base contract of all Facet contracts. - * @dev Every module must inherit from this contract. - */ -abstract contract FacetBase is Store { - modifier onlyOwner() { - require(_msgSender() == owner(), "Ownable: caller is not the owner"); - _; - } - - function owner() public view returns (address) { - // Make an external call to delegatecall the OwnershipFacet. - return IERC5313(address(this)).owner(); - } - - function _msgSender() internal view returns (address) { - return msg.sender; - } -} From 6b9ddca108858764c2d86b5bcdce8e8fe1d2c6de Mon Sep 17 00:00:00 2001 From: gfournieriExec Date: Fri, 25 Jul 2025 17:35:23 +0200 Subject: [PATCH 4/6] feat: Update contract references from delegate to facet naming in multiple files --- .solcover.js | 2 +- CHANGELOG.md | 1 + contracts/Store.v8.sol | 8 ++++---- scripts/tools/sol-to-uml.mjs | 16 ++++++++-------- scripts/tools/storage-to-diagrams.mjs | 2 +- test/000_fullchain-boost.test.ts | 4 ++-- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/.solcover.js b/.solcover.js index 13869b974..e29903654 100644 --- a/.solcover.js +++ b/.solcover.js @@ -21,7 +21,7 @@ module.exports = { 'tools/testing/ERC1271Mock.sol', 'tools/testing/TestClient.sol', 'tools/testing/TestReceiver.sol', - 'modules/delegates/SignatureVerifier.sol', + 'modules/facets/SignatureVerifier.sol', ], istanbulFolder: BASE_FOLDER, }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f8f9173b..bf899c530 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## vNEXT - Migrate proxy to Diamond pattern (ERC-2535): + - Rename ERC1538 architure to diamond Proxy architecture(#226, #229, ) - Remove ENS module (#225) - Add Diamond contract unit tests (#224) - Fix `fallback` and `receive` (#223) diff --git a/contracts/Store.v8.sol b/contracts/Store.v8.sol index f01e17d17..479acc1ff 100644 --- a/contracts/Store.v8.sol +++ b/contracts/Store.v8.sol @@ -92,7 +92,7 @@ abstract contract Store { /** * @dev EIP-712 domain hash. */ - // Modified in IexecMaintenanceDelegate.updateDomainSeparator + // Modified in IexecMaintenanceFacet.updateDomainSeparator //slither-disable-next-line constable-states bytes32 internal EIP712DOMAIN_SEPARATOR; @@ -125,14 +125,14 @@ abstract contract Store { /** * @dev Address of a trusted TEE authority that manages enclave challenges. */ - // Modified in IexecMaintenanceDelegate.setTeeBroker + // Modified in IexecMaintenanceFacet.setTeeBroker //slither-disable-next-line constable-states address internal m_teebroker; /** * @dev Max amount of gas to be used with callbacks. */ - // Modified in IexecMaintenanceDelegate.setCallbackGas + // Modified in IexecMaintenanceFacet.setCallbackGas //slither-disable-next-line constable-states uint256 internal m_callbackgas; @@ -142,7 +142,7 @@ abstract contract Store { IexecLibCore_v5.Category[] internal m_categories; // Backward compatibility - // Modified in IexecMaintenanceDelegate.configure + // Modified in IexecMaintenanceFacet.configure //slither-disable-next-line constable-states address internal m_v3_iexecHub; // IexecHubInterface mapping(address => bool) internal m_v3_scoreImported; diff --git a/scripts/tools/sol-to-uml.mjs b/scripts/tools/sol-to-uml.mjs index 3ec773ecc..eb7df4994 100644 --- a/scripts/tools/sol-to-uml.mjs +++ b/scripts/tools/sol-to-uml.mjs @@ -14,25 +14,25 @@ await generateClassDiagramOfDirectory('registries') await generateClassDiagramOfContracts( [ - 'IexecPoco1Delegate', - 'IexecPoco2Delegate' + 'IexecPoco1Facet', + 'IexecPoco2Facet' ], - 'IexecPocoDelegates', + 'IexecPocoFacets', ) await generateClassDiagramOfContracts( [ - 'IexecEscrowNativeDelegate', - 'IexecEscrowTokenDelegate', - 'IexecEscrowTokenSwapDelegate', + 'IexecEscrowNativeFacet', + 'IexecEscrowTokenFacet', + 'IexecEscrowTokenSwapFacet', 'IexecEscrow', ], 'IexecEscrows', ) await generateClassDiagramOfContracts( - ['IexecPocoBoostDelegate'], - 'IexecPocoBoostDelegate', + ['IexecPocoBoostFacet'], + 'IexecPocoBoostFacet', ) /** diff --git a/scripts/tools/storage-to-diagrams.mjs b/scripts/tools/storage-to-diagrams.mjs index 034220b21..7b96ffaa0 100644 --- a/scripts/tools/storage-to-diagrams.mjs +++ b/scripts/tools/storage-to-diagrams.mjs @@ -7,7 +7,7 @@ $.verbose = false // Disable bash commands logging. const projectRootDir = await $`dirname ${__dirname}` -generateStorageDiagram('IexecPocoBoostDelegate') +generateStorageDiagram('IexecPocoBoostFacet') /** * Generate storage diagram of a given contract. diff --git a/test/000_fullchain-boost.test.ts b/test/000_fullchain-boost.test.ts index e22218d82..501eb6948 100644 --- a/test/000_fullchain-boost.test.ts +++ b/test/000_fullchain-boost.test.ts @@ -46,7 +46,7 @@ const appPrice = 1000n; const datasetPrice = 1_000_000n; const workerpoolPrice = 1_000_000_000n; -describe('IexecPocoBoostDelegate (IT)', function () { +describe('IexecPocoBoostFacet (IT)', function () { let domain: TypedDataDomain; let proxyAddress: string; let iexecInstance: IexecAccessors; @@ -72,7 +72,7 @@ describe('IexecPocoBoostDelegate (IT)', function () { let ordersAssets: OrdersAssets; let ordersPrices: OrdersPrices; - beforeEach('Deploy IexecPocoBoostDelegate', async () => { + beforeEach('Deploy IexecPocoBoostFacet', async () => { // We define a fixture to reuse the same setup in every test. // We use loadFixture to run this setup once, snapshot that state, // and reset Hardhat Network to that snapshot in every test. From 324185fa5877d162c6bb8fa9817e20f4190b2e88 Mon Sep 17 00:00:00 2001 From: gfournieriExec Date: Fri, 25 Jul 2025 17:37:08 +0200 Subject: [PATCH 5/6] fix: Correct typo in changelog for ERC1538 architecture renaming --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf899c530..932fe79dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## vNEXT - Migrate proxy to Diamond pattern (ERC-2535): - - Rename ERC1538 architure to diamond Proxy architecture(#226, #229, ) + - Rename ERC1538 architure to diamond Proxy architecture(#226, #229, #230) - Remove ENS module (#225) - Add Diamond contract unit tests (#224) - Fix `fallback` and `receive` (#223) From 0834b51a3887d2b6178772676f2325cbb78fe71f Mon Sep 17 00:00:00 2001 From: Zied <26070035+zguesmi@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:27:41 +0200 Subject: [PATCH 6/6] Update comment --- contracts/tools/testing/slither/Slither.sol | 2 +- contracts/tools/testing/slither/SlitherBoost.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/tools/testing/slither/Slither.sol b/contracts/tools/testing/slither/Slither.sol index b835e3574..f5e56cfa4 100644 --- a/contracts/tools/testing/slither/Slither.sol +++ b/contracts/tools/testing/slither/Slither.sol @@ -10,7 +10,7 @@ import {IexecPoco2Facet} from "../../../modules/facets/IexecPoco2Facet.sol"; /** * @notice This contract is dedicated to slither analysis. * - * @dev This contract aggregates multiple delegate contracts into a single entry point + * @dev This contract aggregates multiple facet contracts into a single entry point * to facilitate static analysis using Slither. */ //slither-disable-start unused-state diff --git a/contracts/tools/testing/slither/SlitherBoost.sol b/contracts/tools/testing/slither/SlitherBoost.sol index 048945ad8..35bec0a33 100644 --- a/contracts/tools/testing/slither/SlitherBoost.sol +++ b/contracts/tools/testing/slither/SlitherBoost.sol @@ -9,7 +9,7 @@ import {IexecPocoBoostFacet} from "../../../modules/facets/IexecPocoBoostFacet.s /** * @notice This contract is dedicated to slither analysis. * - * @dev This contract aggregates multiple delegate contracts into a single entry point + * @dev This contract aggregates multiple facet contracts into a single entry point * to facilitate static analysis using Slither. */ //slither-disable-start unused-state