diff --git a/CHANGELOG.md b/CHANGELOG.md index 83f125f2c..3cf43b2fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ ## vNEXT - Migrate proxy to Diamond pattern (ERC-2535): + - Restore compatibility with iExec SDK. (#240) + - Target latest EVM version (#239) + - Adapt contracts file tree (#238) + - Use namespaced storage (#236, #237) - Format all solidity files (#233) - Rename ERC1538 architure to diamond Proxy architecture(#226, #229, #230, #234) - Remove ENS module (#225) diff --git a/contracts/IexecInterfaceNative.sol b/contracts/IexecInterfaceNative.sol new file mode 100644 index 000000000..114a2772b --- /dev/null +++ b/contracts/IexecInterfaceNative.sol @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "./interfaces/IOwnable.sol"; +import "./interfaces/IexecAccessors.sol"; +import "./interfaces/IexecCategoryManager.sol"; +import "./interfaces/IexecERC20.sol"; +import "./interfaces/IexecEscrowNative.sol"; +import "./interfaces/IexecConfiguration.sol"; +import "./interfaces/IexecOrderManagement.sol"; +import "./interfaces/IexecPoco1.sol"; +import "./interfaces/IexecPoco2.sol"; +import "./interfaces/IexecRelay.sol"; +import "./interfaces/IexecTokenSpender.sol"; + +/** + * A global interface that aggregates all the interfaces needed to interact with + * the PoCo contracts in native mode. + * @dev Referenced in the SDK with the current path `contracts/IexecInterfaceNative.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ +interface IexecInterfaceNative is + IOwnable, + IexecAccessors, + IexecCategoryManager, + IexecERC20, + IexecEscrowNative, + IexecConfiguration, + IexecOrderManagement, + IexecPoco1, + IexecPoco2, + IexecRelay, + IexecTokenSpender +{} diff --git a/contracts/IexecInterfaceNativeABILegacy.sol b/contracts/IexecInterfaceNativeABILegacy.sol new file mode 100644 index 000000000..d6c83cb43 --- /dev/null +++ b/contracts/IexecInterfaceNativeABILegacy.sol @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "./interfaces/IOwnable.sol"; +import "./interfaces/IexecAccessors.sol"; +import "./interfaces/IexecAccessorsABILegacy.sol"; +import "./interfaces/IexecCategoryManager.sol"; +import "./interfaces/IexecERC20.sol"; +import "./interfaces/IexecEscrowNative.sol"; +import "./interfaces/IexecConfiguration.sol"; +import "./interfaces/IexecOrderManagement.sol"; +import "./interfaces/IexecPoco1.sol"; +import "./interfaces/IexecPoco2.sol"; +import "./interfaces/IexecRelay.sol"; +import "./interfaces/IexecTokenSpender.sol"; + +/** + * TODO: Remove this interface in the future when IexecInterfaceTokenABILegacy is removed. + */ +interface IexecInterfaceNativeABILegacy is + IOwnable, + IexecAccessors, + IexecAccessorsABILegacy, + IexecCategoryManager, + IexecERC20, + IexecEscrowNative, + IexecConfiguration, + IexecOrderManagement, + IexecPoco1, + IexecPoco2, + IexecRelay, + IexecTokenSpender +{} diff --git a/contracts/IexecInterfaceToken.sol b/contracts/IexecInterfaceToken.sol new file mode 100644 index 000000000..a27ca471d --- /dev/null +++ b/contracts/IexecInterfaceToken.sol @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "./interfaces/IOwnable.sol"; +import "./interfaces/IexecAccessors.sol"; +import "./interfaces/IexecCategoryManager.sol"; +import "./interfaces/IexecERC20.sol"; +import "./interfaces/IexecEscrowToken.sol"; +import "./interfaces/IexecEscrowTokenSwap.sol"; +import "./interfaces/IexecConfiguration.sol"; +import "./interfaces/IexecOrderManagement.sol"; +import "./interfaces/IexecPoco1.sol"; +import "./interfaces/IexecPoco2.sol"; +import "./interfaces/IexecRelay.sol"; +import "./interfaces/IexecTokenSpender.sol"; + +/** + * A global interface that aggregates all the interfaces needed to interact with + * the PoCo contracts in token mode. + * @dev Referenced in the SDK with the current path `contracts/IexecInterfaceToken.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ +interface IexecInterfaceToken is + IOwnable, + IexecAccessors, + IexecCategoryManager, + IexecERC20, + IexecEscrowToken, + IexecEscrowTokenSwap, + IexecConfiguration, + IexecOrderManagement, + IexecPoco1, + IexecPoco2, + IexecRelay, + IexecTokenSpender +{ + receive() external payable override(IexecEscrowToken, IexecEscrowTokenSwap); + fallback() external payable override(IexecEscrowToken, IexecEscrowTokenSwap); +} diff --git a/contracts/IexecInterfaceTokenABILegacy.sol b/contracts/IexecInterfaceTokenABILegacy.sol new file mode 100644 index 000000000..9d3dec690 --- /dev/null +++ b/contracts/IexecInterfaceTokenABILegacy.sol @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity ^0.6.0; +pragma experimental ABIEncoderV2; + +import "./interfaces/IOwnable.sol"; +import "./interfaces/IexecAccessors.sol"; +import "./interfaces/IexecAccessorsABILegacy.sol"; +import "./interfaces/IexecCategoryManager.sol"; +import "./interfaces/IexecERC20.sol"; +import "./interfaces/IexecEscrowToken.sol"; +import "./interfaces/IexecEscrowTokenSwap.sol"; +import "./interfaces/IexecConfiguration.sol"; +import "./interfaces/IexecOrderManagement.sol"; +import "./interfaces/IexecPoco1.sol"; +import "./interfaces/IexecPoco2.sol"; +import "./interfaces/IexecRelay.sol"; +import "./interfaces/IexecTokenSpender.sol"; + +/** + * TODO: Remove this interface in the future. + * Currently Used in the middleware: + * https://github.com/iExecBlockchainComputing/iexec-commons-poco/blob/819cd008/generateContractWrappers#L7 + */ +interface IexecInterfaceTokenABILegacy is + IOwnable, + IexecAccessors, + IexecAccessorsABILegacy, + IexecCategoryManager, + IexecERC20, + IexecEscrowToken, + IexecEscrowTokenSwap, + IexecConfiguration, + IexecOrderManagement, + IexecPoco1, + IexecPoco2, + IexecRelay, + IexecTokenSpender +{ + receive() external payable override(IexecEscrowToken, IexecEscrowTokenSwap); + fallback() external payable override(IexecEscrowToken, IexecEscrowTokenSwap); +} diff --git a/contracts/Store.sol b/contracts/Store.sol index aa7bb5509..c04f383e3 100644 --- a/contracts/Store.sol +++ b/contracts/Store.sol @@ -61,28 +61,28 @@ abstract contract Store { // In order to use the protocol, users have to deposit RLC // and allow PoCo smart contracts to manage them. This state // variable keeps track of users balances. - mapping(address => uint256) m_balances; + mapping(address /* account */ => uint256 /* amount */) m_balances; // When a deal is created, the protocol temporarily locks an amount // of RLC tokens from the balances of both the requester and the workerpool owners. // This is to guarantee the payment of different actors later. Frozen funds // are released when the computation is completed and the result is pushed. - mapping(address => uint256) m_frozens; - mapping(address => mapping(address => uint256)) m_allowances; + mapping(address /* account */ => uint256 /* amount */) m_frozens; + mapping(address /* owner */ => mapping(address /* spender */ => uint256 /* amount */)) m_allowances; // EIP-712 domain hash. // Modified in IexecConfigurationFacet.updateDomainSeparator bytes32 m_eip712DomainSeparator; // Mapping an order hash to its owner. Since a smart contract cannot sign orders // with a private key, it adds an entry to this mapping to provide presigned orders. - mapping(bytes32 => address) m_presigned; + mapping(bytes32 /* orderHash */ => address /* owner */) m_presigned; // Each order has a volume (>=1). This tracks how much is consumed from // the volume of each order. Mapping an order hash to its consumed amount. - mapping(bytes32 => uint256) m_consumed; + mapping(bytes32 /* orderHash */ => uint256 /* consumedAmount */) m_consumed; // a mapping to store PoCo classic deals. - mapping(bytes32 => IexecLibCore_v5.Deal) m_deals; - mapping(bytes32 => IexecLibCore_v5.Task) m_tasks; // per task - mapping(bytes32 => IexecLibCore_v5.Consensus) m_consensus; // per task - mapping(bytes32 => mapping(address => IexecLibCore_v5.Contribution)) m_contributions; // per task-worker - mapping(address => uint256) m_workerScores; // per worker + mapping(bytes32 /* dealId */ => IexecLibCore_v5.Deal) m_deals; + mapping(bytes32 /* taskId */ => IexecLibCore_v5.Task) m_tasks; + mapping(bytes32 /* taskId */ => IexecLibCore_v5.Consensus) m_consensus; + mapping(bytes32 /* taskId */ => mapping(address /* worker */ => IexecLibCore_v5.Contribution)) m_contributions; + mapping(address /* worker */ => uint256 /* score */) m_workerScores; // Poco - Settings // Address of a trusted TEE authority that manages enclave challenges. // Modified in IexecConfigurationFacet.setTeeBroker @@ -95,7 +95,7 @@ abstract contract Store { // Backward compatibility // Modified in IexecConfigurationFacet.configure IexecHubInterface m_v3_iexecHub; - mapping(address => bool) m_v3_scoreImported; + mapping(address /* worker */ => bool) m_v3_scoreImported; } function getPocoStorage() internal pure returns (PocoStorage storage $) { diff --git a/contracts/Store.v8.sol b/contracts/Store.v8.sol index 880f3c2ca..cb5c0f948 100644 --- a/contracts/Store.v8.sol +++ b/contracts/Store.v8.sol @@ -55,28 +55,28 @@ abstract contract Store { // In order to use the protocol, users have to deposit RLC // and allow PoCo smart contracts to manage them. This state // variable keeps track of users balances. - mapping(address => uint256) m_balances; + mapping(address /* account */ => uint256 /* amount */) m_balances; // When a deal is created, the protocol temporarily locks an amount // of RLC tokens from the balances of both the requester and the workerpool owners. // This is to guarantee the payment of different actors later. Frozen funds // are released when the computation is completed and the result is pushed. - mapping(address => uint256) m_frozens; - mapping(address => mapping(address => uint256)) m_allowances; + mapping(address /* account */ => uint256 /* amount */) m_frozens; + mapping(address /* owner */ => mapping(address /* spender */ => uint256 /* amount */)) m_allowances; // EIP-712 domain hash. // Modified in IexecConfigurationFacet.updateDomainSeparator bytes32 m_eip712DomainSeparator; // Mapping an order hash to its owner. Since a smart contract cannot sign orders // with a private key, it adds an entry to this mapping to provide presigned orders. - mapping(bytes32 => address) m_presigned; + mapping(bytes32 /* orderHash */ => address /* owner */) m_presigned; // Each order has a volume (>=1). This tracks how much is consumed from // the volume of each order. Mapping an order hash to its consumed amount. - mapping(bytes32 => uint256) m_consumed; + mapping(bytes32 /* orderHash */ => uint256 /* consumedAmount */) m_consumed; // a mapping to store PoCo classic deals. - mapping(bytes32 => IexecLibCore_v5.Deal) m_deals; - mapping(bytes32 => IexecLibCore_v5.Task) m_tasks; // per task - mapping(bytes32 => IexecLibCore_v5.Consensus) m_consensus; // per task - mapping(bytes32 => mapping(address => IexecLibCore_v5.Contribution)) m_contributions; // per task-worker - mapping(address => uint256) m_workerScores; // per worker + mapping(bytes32 /* dealId */ => IexecLibCore_v5.Deal) m_deals; + mapping(bytes32 /* taskId */ => IexecLibCore_v5.Task) m_tasks; + mapping(bytes32 /* taskId */ => IexecLibCore_v5.Consensus) m_consensus; + mapping(bytes32 /* taskId */ => mapping(address /* worker */ => IexecLibCore_v5.Contribution)) m_contributions; + mapping(address /* worker */ => uint256 /* score */) m_workerScores; // Poco - Settings // Address of a trusted TEE authority that manages enclave challenges. // Modified in IexecConfigurationFacet.setTeeBroker @@ -89,10 +89,10 @@ abstract contract Store { // Backward compatibility // Modified in IexecConfigurationFacet.configure address m_v3_iexecHub; // IexecHubInterface - mapping(address => bool) m_v3_scoreImported; + mapping(address /* worker */ => bool) m_v3_scoreImported; // /!\ New storage variables not present in v6 store. // A mapping to store PoCo Boost deals. - mapping(bytes32 => IexecLibCore_v5.DealBoost) m_dealsBoost; + mapping(bytes32 /* dealId */ => IexecLibCore_v5.DealBoost) m_dealsBoost; } function getPocoStorage() internal pure returns (PocoStorage storage $) { diff --git a/contracts/interfaces/IexecAccessorsABILegacy.sol b/contracts/interfaces/IexecAccessorsABILegacy.sol index 7cfa142cf..355ba97be 100644 --- a/contracts/interfaces/IexecAccessorsABILegacy.sol +++ b/contracts/interfaces/IexecAccessorsABILegacy.sol @@ -6,6 +6,11 @@ pragma experimental ABIEncoderV2; import "../libs/IexecLibCore_v5.sol"; +/** + * TODO: Remove this interface in the future. + * Currently Used in the middleware: + * https://github.com/iExecBlockchainComputing/iexec-commons-poco/blob/819cd008/src/main/java/com/iexec/commons/poco/chain/IexecHubAbstractService.java#L265 + */ interface IexecAccessorsABILegacy { function viewAccountABILegacy(address _user) external view returns (uint256, uint256); diff --git a/contracts/interfaces/IexecInterfaceNative.sol b/contracts/interfaces/IexecInterfaceNative.sol deleted file mode 100644 index a252995f3..000000000 --- a/contracts/interfaces/IexecInterfaceNative.sol +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "./IOwnable.sol"; -import "./IexecAccessors.sol"; -import "./IexecCategoryManager.sol"; -import "./IexecERC20.sol"; -import "./IexecEscrowNative.sol"; -import "./IexecConfiguration.sol"; -import "./IexecOrderManagement.sol"; -import "./IexecPoco1.sol"; -import "./IexecPoco2.sol"; -import "./IexecRelay.sol"; -import "./IexecTokenSpender.sol"; - -interface IexecInterfaceNative is - IOwnable, - IexecAccessors, - IexecCategoryManager, - IexecERC20, - IexecEscrowNative, - IexecConfiguration, - IexecOrderManagement, - IexecPoco1, - IexecPoco2, - IexecRelay, - IexecTokenSpender -{} diff --git a/contracts/interfaces/IexecInterfaceNativeABILegacy.sol b/contracts/interfaces/IexecInterfaceNativeABILegacy.sol deleted file mode 100644 index 2c0ce51a0..000000000 --- a/contracts/interfaces/IexecInterfaceNativeABILegacy.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "./IOwnable.sol"; -import "./IexecAccessors.sol"; -import "./IexecAccessorsABILegacy.sol"; -import "./IexecCategoryManager.sol"; -import "./IexecERC20.sol"; -import "./IexecEscrowNative.sol"; -import "./IexecConfiguration.sol"; -import "./IexecOrderManagement.sol"; -import "./IexecPoco1.sol"; -import "./IexecPoco2.sol"; -import "./IexecRelay.sol"; -import "./IexecTokenSpender.sol"; - -interface IexecInterfaceNativeABILegacy is - IOwnable, - IexecAccessors, - IexecAccessorsABILegacy, - IexecCategoryManager, - IexecERC20, - IexecEscrowNative, - IexecConfiguration, - IexecOrderManagement, - IexecPoco1, - IexecPoco2, - IexecRelay, - IexecTokenSpender -{} diff --git a/contracts/interfaces/IexecInterfaceToken.sol b/contracts/interfaces/IexecInterfaceToken.sol deleted file mode 100644 index d9932f3da..000000000 --- a/contracts/interfaces/IexecInterfaceToken.sol +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "./IOwnable.sol"; -import "./IexecAccessors.sol"; -import "./IexecCategoryManager.sol"; -import "./IexecERC20.sol"; -import "./IexecEscrowToken.sol"; -import "./IexecEscrowTokenSwap.sol"; -import "./IexecConfiguration.sol"; -import "./IexecOrderManagement.sol"; -import "./IexecPoco1.sol"; -import "./IexecPoco2.sol"; -import "./IexecRelay.sol"; -import "./IexecTokenSpender.sol"; - -interface IexecInterfaceToken is - IOwnable, - IexecAccessors, - IexecCategoryManager, - IexecERC20, - IexecEscrowToken, - IexecEscrowTokenSwap, - IexecConfiguration, - IexecOrderManagement, - IexecPoco1, - IexecPoco2, - IexecRelay, - IexecTokenSpender -{ - receive() external payable override(IexecEscrowToken, IexecEscrowTokenSwap); - fallback() external payable override(IexecEscrowToken, IexecEscrowTokenSwap); -} diff --git a/contracts/interfaces/IexecInterfaceTokenABILegacy.sol b/contracts/interfaces/IexecInterfaceTokenABILegacy.sol deleted file mode 100644 index 91f3f97a2..000000000 --- a/contracts/interfaces/IexecInterfaceTokenABILegacy.sol +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-FileCopyrightText: 2020-2025 IEXEC BLOCKCHAIN TECH -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; - -import "./IOwnable.sol"; -import "./IexecAccessors.sol"; -import "./IexecAccessorsABILegacy.sol"; -import "./IexecCategoryManager.sol"; -import "./IexecERC20.sol"; -import "./IexecEscrowToken.sol"; -import "./IexecEscrowTokenSwap.sol"; -import "./IexecConfiguration.sol"; -import "./IexecOrderManagement.sol"; -import "./IexecPoco1.sol"; -import "./IexecPoco2.sol"; -import "./IexecRelay.sol"; -import "./IexecTokenSpender.sol"; - -interface IexecInterfaceTokenABILegacy is - IOwnable, - IexecAccessors, - IexecAccessorsABILegacy, - IexecCategoryManager, - IexecERC20, - IexecEscrowToken, - IexecEscrowTokenSwap, - IexecConfiguration, - IexecOrderManagement, - IexecPoco1, - IexecPoco2, - IexecRelay, - IexecTokenSpender -{ - receive() external payable override(IexecEscrowToken, IexecEscrowTokenSwap); - fallback() external payable override(IexecEscrowToken, IexecEscrowTokenSwap); -} diff --git a/contracts/registries/Registry.sol b/contracts/registries/Registry.sol index 6b924378b..66c0ade93 100644 --- a/contracts/registries/Registry.sol +++ b/contracts/registries/Registry.sol @@ -32,6 +32,28 @@ abstract contract Registry is IRegistry, ERC721, Ownable { previous = IRegistry(_previous); } + function setBaseURI(string calldata _baseURI) external onlyOwner { + _setBaseURI(_baseURI); + } + + /* Interface */ + function isRegistered(address _entry) external view override returns (bool) { + return + _exists(uint256(_entry)) || + (address(previous) != address(0) && previous.isRegistered(_entry)); + } + + /** + * Sets the reverse registration name for a registry contract. + * @dev This functionality is supported only on the Bellecour chain. + * On other chains, this function will revert to maintain retrocompatibility + * in the SDK. + */ + // TODO remove this function when Bellecour is deprecated. + function setName(address /* _ens */, string calldata /* _name */) external view onlyOwner() { + revert("Operation not supported on this chain"); + } + /* Factory */ function _mintCreate(address _owner, bytes memory _args) internal returns (uint256) { // Create entry (proxy) @@ -50,15 +72,4 @@ abstract contract Registry is IRegistry, ERC721, Ownable { ); return uint256(entry); } - - function setBaseURI(string calldata _baseURI) external onlyOwner { - _setBaseURI(_baseURI); - } - - /* Interface */ - function isRegistered(address _entry) external view override returns (bool) { - return - _exists(uint256(_entry)) || - (address(previous) != address(0) && previous.isRegistered(_entry)); - } } diff --git a/contracts/registries/RegistryEntry.sol b/contracts/registries/RegistryEntry.sol index a3a873f7d..c8efded62 100644 --- a/contracts/registries/RegistryEntry.sol +++ b/contracts/registries/RegistryEntry.sol @@ -5,20 +5,35 @@ pragma solidity ^0.6.0; import "./Registry.sol"; +/** + * @dev Referenced in the SDK with the current path `contracts/registries/RegistryEntry.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ abstract contract RegistryEntry { IRegistry public registry; - function _initialize(address _registry) internal { - require(address(registry) == address(0), "already initialized"); - registry = IRegistry(_registry); + modifier onlyOwner() { + require(owner() == msg.sender, "caller is not the owner"); + _; } function owner() public view returns (address) { return registry.ownerOf(uint256(address(this))); } - modifier onlyOwner() { - require(owner() == msg.sender, "caller is not the owner"); - _; + /** + * Sets the reverse registration name for a registry entry contract. + * @dev This functionality is supported only on the Bellecour chain. + * On other chains, this function will revert to maintain retrocompatibility + * in the SDK. + */ + // TODO remove this function when Bellecour is deprecated. + function setName(address /* _ens */, string calldata /* _name */) external view onlyOwner() { + revert("Operation not supported on this chain"); + } + + function _initialize(address _registry) internal { + require(address(registry) == address(0), "already initialized"); + registry = IRegistry(_registry); } } diff --git a/contracts/registries/apps/App.sol b/contracts/registries/apps/App.sol index 7196cd4d2..ba1adff69 100644 --- a/contracts/registries/apps/App.sol +++ b/contracts/registries/apps/App.sol @@ -5,6 +5,10 @@ pragma solidity ^0.6.0; import "../RegistryEntry.sol"; +/** + * @dev Referenced in the SDK with the current path `contracts/registries/apps/AppRegistry.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ contract App is RegistryEntry { /** * Members diff --git a/contracts/registries/apps/AppRegistry.sol b/contracts/registries/apps/AppRegistry.sol index 7c1acbbe4..6d542a561 100644 --- a/contracts/registries/apps/AppRegistry.sol +++ b/contracts/registries/apps/AppRegistry.sol @@ -6,6 +6,10 @@ pragma solidity ^0.6.0; import "../Registry.sol"; import "./App.sol"; +/** + * @dev Referenced in the SDK with the current path `contracts/registries/apps/AppRegistry.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ contract AppRegistry is Registry { /** * Constructor diff --git a/contracts/registries/datasets/Dataset.sol b/contracts/registries/datasets/Dataset.sol index 158b4e3a3..d6d7bb514 100644 --- a/contracts/registries/datasets/Dataset.sol +++ b/contracts/registries/datasets/Dataset.sol @@ -5,6 +5,10 @@ pragma solidity ^0.6.0; import "../RegistryEntry.sol"; +/** + * @dev Referenced in the SDK with the current path `contracts/registries/datasets/Dataset.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ contract Dataset is RegistryEntry { /** * Members diff --git a/contracts/registries/datasets/DatasetRegistry.sol b/contracts/registries/datasets/DatasetRegistry.sol index 56b65e421..ca5cfd818 100644 --- a/contracts/registries/datasets/DatasetRegistry.sol +++ b/contracts/registries/datasets/DatasetRegistry.sol @@ -6,6 +6,10 @@ pragma solidity ^0.6.0; import "../Registry.sol"; import "./Dataset.sol"; +/** + * @dev Referenced in the SDK with the current path `contracts/registries/datasets/DatasetRegistry.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ contract DatasetRegistry is Registry { /** * Constructor diff --git a/contracts/registries/workerpools/Workerpool.sol b/contracts/registries/workerpools/Workerpool.sol index 693996431..c9ad8e95f 100644 --- a/contracts/registries/workerpools/Workerpool.sol +++ b/contracts/registries/workerpools/Workerpool.sol @@ -5,6 +5,10 @@ pragma solidity ^0.6.0; import "../RegistryEntry.sol"; +/** + * @dev Referenced in the SDK with the current path `contracts/registries/workerpools/Workerpool.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ contract Workerpool is RegistryEntry { /** * Parameters diff --git a/contracts/registries/workerpools/WorkerpoolRegistry.sol b/contracts/registries/workerpools/WorkerpoolRegistry.sol index 319ad5871..26908e863 100644 --- a/contracts/registries/workerpools/WorkerpoolRegistry.sol +++ b/contracts/registries/workerpools/WorkerpoolRegistry.sol @@ -6,6 +6,10 @@ pragma solidity ^0.6.0; import "../Registry.sol"; import "./Workerpool.sol"; +/** + * @dev Referenced in the SDK with the current path `contracts/registries/workerpools/WorkerpoolRegistry.sol`. + * Changing the name or the path would cause a breaking change in the SDK. + */ contract WorkerpoolRegistry is Registry { /** * Constructor diff --git a/package.json b/package.json index 7313620fe..364d3682e 100644 --- a/package.json +++ b/package.json @@ -86,4 +86,4 @@ "sol2uml": "After 2.5.19, see https://github.com/naddison36/sol2uml/issues/183", "solidity-coverage": "Fixing Hardhat's solidity-coverage: TypeError: provider.send is not a function" } -} \ No newline at end of file +} diff --git a/test/000_fullchain-boost.test.ts b/test/000_fullchain-boost.test.ts index 501eb6948..6a2cdcf39 100644 --- a/test/000_fullchain-boost.test.ts +++ b/test/000_fullchain-boost.test.ts @@ -37,6 +37,7 @@ import { } from '../utils/poco-tools'; import { IexecWrapper } from './utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer'; +import { randomAddress } from './utils/utils'; const teeDealTag = '0x0000000000000000000000000000000000000000000000000000000000000001'; const taskIndex = 0n; @@ -129,7 +130,7 @@ describe('IexecPocoBoostFacet (IT)', function () { describe('MatchOrders', function () { it('Should match orders (TEE)', async function () { - const callbackAddress = ethers.Wallet.createRandom().address; + const callbackAddress = randomAddress(); const orders = buildOrders({ assets: ordersAssets, requester: requester.address, @@ -288,7 +289,7 @@ describe('IexecPocoBoostFacet (IT)', function () { }); it('Should sponsor match orders (TEE)', async function () { - const callbackAddress = ethers.Wallet.createRandom().address; + const callbackAddress = randomAddress(); const orders = buildOrders({ assets: ordersAssets, requester: requester.address, diff --git a/test/000_fullchain.test.ts b/test/000_fullchain.test.ts index 31f971de5..2a94c7592 100644 --- a/test/000_fullchain.test.ts +++ b/test/000_fullchain.test.ts @@ -16,6 +16,7 @@ import { } from '../utils/poco-tools'; import { IexecWrapper } from './utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from './utils/hardhat-fixture-deployer'; +import { randomAddress } from './utils/utils'; // +---------+-------------+-------------+-------------+----------+-----+---------------------------------------------+ // | | Sponsorship | Replication | Beneficiary | Callback | BoT | Type | @@ -34,7 +35,7 @@ const teeDealTag = '0x0000000000000000000000000000000000000000000000000000000000 const appPrice = 1000n; const datasetPrice = 1_000_000n; const workerpoolPrice = 1_000_000_000n; -const callbackAddress = ethers.Wallet.createRandom().address; +const callbackAddress = randomAddress(); const { results, resultDigest } = buildUtf8ResultAndDigest('result'); const { resultsCallback, callbackResultDigest } = buildResultCallbackAndDigest(123); diff --git a/test/byContract/IexecAccessors/IexecAccessors.test.ts b/test/byContract/IexecAccessors/IexecAccessors.test.ts index 76277af14..c65f79ff4 100644 --- a/test/byContract/IexecAccessors/IexecAccessors.test.ts +++ b/test/byContract/IexecAccessors/IexecAccessors.test.ts @@ -28,7 +28,7 @@ import { } from '../../../utils/poco-tools'; import { IexecWrapper } from '../../utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; -import { hashDomain } from '../../utils/utils'; +import { hashDomain, randomAddress } from '../../utils/utils'; /** * Test state view functions. @@ -104,7 +104,7 @@ describe('IexecAccessors', async () => { it('allowance', async function () { const amount = 10n; - const spender = ethers.Wallet.createRandom().address; + const spender = randomAddress(); await iexecWrapper.depositInIexecAccount(anyone, amount); await iexecPoco.connect(anyone).approve(spender, amount); expect(await iexecPoco.allowance(anyone.address, spender)).to.equal(amount); diff --git a/test/byContract/IexecConfiguration/IexecConfiguration.test.ts b/test/byContract/IexecConfiguration/IexecConfiguration.test.ts index ee91fec42..0002d958d 100644 --- a/test/byContract/IexecConfiguration/IexecConfiguration.test.ts +++ b/test/byContract/IexecConfiguration/IexecConfiguration.test.ts @@ -15,9 +15,8 @@ import { import { getIexecAccounts } from '../../../utils/poco-tools'; import { getPocoStorageSlotLocation } from '../../../utils/proxy-tools'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; -import { hashDomain } from '../../utils/utils'; +import { hashDomain, randomAddress } from '../../utils/utils'; -const randomAddress = () => ethers.Wallet.createRandom().address; const configureParams = { token: randomAddress(), name: 'some name', diff --git a/test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts b/test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts index 3e8e40c1f..a21a415f8 100644 --- a/test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts +++ b/test/byContract/IexecPocoBoost/IexecPocoBoost.test.ts @@ -58,6 +58,7 @@ import { } from '../../../utils/poco-tools'; import { IexecWrapper } from '../../utils/IexecWrapper'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; +import { randomAddress } from '../../utils/utils'; const teeDealTag = '0x0000000000000000000000000000000000000000000000000000000000000001'; const taskIndex = 0n; @@ -69,7 +70,7 @@ const appPrice = 1000n; const datasetPrice = 1_000_000n; const workerpoolPrice = 1_000_000_000n; const someSignature = '0xabcd'; // contract signatures could have arbitrary formats -const randomEOAAddress = ethers.Wallet.createRandom().address; +const randomEOAAddress = randomAddress(); let proxyAddress: string; let iexecPocoBoostInstance: IexecPocoBoostFacet; @@ -173,7 +174,7 @@ describe('IexecPocoBoost', function () { beneficiary: beneficiary.address, tag: teeDealTag, prices: ordersPrices, - callback: ethers.Wallet.createRandom().address, + callback: randomAddress(), }); const { appOrder, @@ -304,7 +305,7 @@ describe('IexecPocoBoost', function () { beneficiary: beneficiary.address, tag: teeDealTag, prices: ordersPrices, - callback: ethers.Wallet.createRandom().address, + callback: randomAddress(), }); const { appOrder, datasetOrder, workerpoolOrder, requestOrder } = orders.toObject(); // Should match orders with low app order volume @@ -1618,7 +1619,7 @@ describe('IexecPocoBoost', function () { assets: ordersAssets, requester: requester.address, tag: teeDealTag, - callback: ethers.Wallet.createRandom().address, + callback: randomAddress(), }); await signOrders(domain, orders, ordersActors); const dealId = getDealId(domain, orders.requester, taskIndex); @@ -1971,7 +1972,7 @@ describe('IexecPocoBoost', function () { assets: ordersAssets, requester: requester.address, tag: teeDealTag, - callback: ethers.Wallet.createRandom().address, + callback: randomAddress(), }); await signOrders(domain, orders, ordersActors); const dealId = getDealId(domain, orders.requester, taskIndex); diff --git a/test/byContract/IexecRelay/IexecRelay.test.ts b/test/byContract/IexecRelay/IexecRelay.test.ts index 17b8752f6..7529a4009 100644 --- a/test/byContract/IexecRelay/IexecRelay.test.ts +++ b/test/byContract/IexecRelay/IexecRelay.test.ts @@ -11,6 +11,7 @@ import { } from '../../../typechain'; import { getIexecAccounts } from '../../../utils/poco-tools'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; +import { randomAddress } from '../../utils/utils'; const appPrice = 1; const datasetPrice = 2; @@ -35,9 +36,7 @@ describe('IexecRelay', async () => { async function initFixture() { const accounts = await getIexecAccounts(); iexecPoco = IexecInterfaceNative__factory.connect(proxyAddress, accounts.anyone); - [app, dataset, workerpool, requester, beneficiary] = Array(5).fill( - ethers.Wallet.createRandom().address, - ); + [app, dataset, workerpool, requester, beneficiary] = Array(5).fill(randomAddress()); sign = await ethers.Wallet.createRandom().signMessage('sign'); } @@ -108,7 +107,7 @@ describe('IexecRelay', async () => { category, trust, beneficiary, - callback: ethers.Wallet.createRandom().address, + callback: randomAddress(), params: 'params', salt, sign, diff --git a/test/byContract/registries/assets.test.ts b/test/byContract/registries/assets.test.ts index 638f66db2..e5396d30f 100644 --- a/test/byContract/registries/assets.test.ts +++ b/test/byContract/registries/assets.test.ts @@ -25,6 +25,34 @@ import { import { MULTIADDR_BYTES } from '../../../utils/constants'; import { getIexecAccounts } from '../../../utils/poco-tools'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; +import { randomAddress } from '../../utils/utils'; + +const createAppParams = { + name: 'My app', + type: 'DOCKER', + multiaddr: MULTIADDR_BYTES, + checksum: ethers.id('My app checksum'), + mreclave: '0x1234', +}; +const createAppArgs = Object.values(createAppParams) as [ + string, + string, + BytesLike, + BytesLike, + BytesLike, +]; + +const createDatasetParams = { + name: 'My dataset', + multiaddr: MULTIADDR_BYTES, + checksum: ethers.id('My dataset checksum'), +}; +const createDatasetArgs = Object.values(createDatasetParams) as [string, BytesLike, BytesLike]; + +const createWorkerpoolParams = { + description: 'Workerpool description', +}; +const createWorkerpoolArgs = Object.values(createWorkerpoolParams) as [string]; describe('Assets', () => { let proxyAddress: string; @@ -58,34 +86,12 @@ describe('Assets', () => { await iexecPoco.workerpoolregistry(), anyone, ); + await deployApp(); + await deployDataset(); + await deployWorkerpool(); } describe('App', () => { - const createAppParams = { - name: 'My app', - type: 'DOCKER', - multiaddr: MULTIADDR_BYTES, - checksum: ethers.id('My app checksum'), - mreclave: '0x1234', - }; - const createAppArgs = Object.values(createAppParams) as [ - string, - string, - BytesLike, - BytesLike, - BytesLike, - ]; - beforeEach(async () => { - const appAddress = await appRegistry.createApp.staticCall( - appProvider.address, - ...createAppArgs, - ); - await appRegistry - .createApp(appProvider.address, ...createAppArgs) - .then((tx) => tx.wait()); - app = App__factory.connect(appAddress, anyone); - }); - describe('creation and initialization', () => { it('Should read initialized app details', async () => { expect(await app.registry()).to.equal(await appRegistry.getAddress()); @@ -106,27 +112,6 @@ describe('Assets', () => { }); describe('Dataset', () => { - const createDatasetParams = { - name: 'My dataset', - multiaddr: MULTIADDR_BYTES, - checksum: ethers.id('My dataset checksum'), - }; - const createDatasetArgs = Object.values(createDatasetParams) as [ - string, - BytesLike, - BytesLike, - ]; - beforeEach(async () => { - const datasetAddress = await datasetRegistry.createDataset.staticCall( - datasetProvider.address, - ...createDatasetArgs, - ); - await datasetRegistry - .createDataset(datasetProvider.address, ...createDatasetArgs) - .then((tx) => tx.wait()); - dataset = Dataset__factory.connect(datasetAddress, anyone); - }); - describe('creation and initialization', () => { it('Should read initialized dataset details', async () => { expect(await dataset.registry()).to.equal(await datasetRegistry.getAddress()); @@ -145,21 +130,6 @@ describe('Assets', () => { }); describe('Workerpool', () => { - const createWorkerpoolParams = { - description: 'Workerpool description', - }; - const createWorkerpoolArgs = Object.values(createWorkerpoolParams) as [string]; - beforeEach(async () => { - const workerpoolAddress = await workerpoolRegistry.createWorkerpool.staticCall( - scheduler.address, - ...createWorkerpoolArgs, - ); - await workerpoolRegistry - .createWorkerpool(scheduler.address, ...createWorkerpoolArgs) - .then((tx) => tx.wait()); - workerpool = Workerpool__factory.connect(workerpoolAddress, anyone); - }); - describe('creation and initialization', () => { it('Should read initialized workerpool details', async () => { expect(await workerpool.registry()).to.equal(await workerpoolRegistry.getAddress()); @@ -214,4 +184,52 @@ describe('Assets', () => { }); }); }); + + describe('Common', () => { + it('Should revert when setName is called for reverse registration', async () => { + const randomEnsContract = randomAddress(); + const randomEnsName = 'random.eth'; + const txs = [ + app.connect(appProvider).setName(randomEnsContract, randomEnsName), + dataset.connect(datasetProvider).setName(randomEnsContract, randomEnsName), + workerpool.connect(scheduler).setName(randomEnsContract, randomEnsName), + ]; + await Promise.all( + txs.map((tx) => + expect(tx).to.be.revertedWith('Operation not supported on this chain'), + ), + ); + }); + }); + + async function deployApp() { + const appAddress = await appRegistry.createApp.staticCall( + appProvider.address, + ...createAppArgs, + ); + await appRegistry.createApp(appProvider.address, ...createAppArgs).then((tx) => tx.wait()); + app = App__factory.connect(appAddress, anyone); + } + + async function deployDataset() { + const datasetAddress = await datasetRegistry.createDataset.staticCall( + datasetProvider.address, + ...createDatasetArgs, + ); + await datasetRegistry + .createDataset(datasetProvider.address, ...createDatasetArgs) + .then((tx) => tx.wait()); + dataset = Dataset__factory.connect(datasetAddress, anyone); + } + + async function deployWorkerpool() { + const workerpoolAddress = await workerpoolRegistry.createWorkerpool.staticCall( + scheduler.address, + ...createWorkerpoolArgs, + ); + await workerpoolRegistry + .createWorkerpool(scheduler.address, ...createWorkerpoolArgs) + .then((tx) => tx.wait()); + workerpool = Workerpool__factory.connect(workerpoolAddress, anyone); + } }); diff --git a/test/byContract/registries/registries.test.ts b/test/byContract/registries/registries.test.ts index bcc3443bc..96f4837d5 100644 --- a/test/byContract/registries/registries.test.ts +++ b/test/byContract/registries/registries.test.ts @@ -25,7 +25,7 @@ import { MULTIADDR_BYTES } from '../../../utils/constants'; import { getIexecAccounts } from '../../../utils/poco-tools'; import { bigintToAddress } from '../../../utils/tools'; import { loadHardhatFixtureDeployment } from '../../utils/hardhat-fixture-deployer'; -const randomAddress = () => ethers.Wallet.createRandom().address; +import { randomAddress } from '../../utils/utils'; describe('Registries', () => { let proxyAddress: string; @@ -472,4 +472,21 @@ describe('Registries', () => { ).to.be.revertedWith('Create2: Failed on deploy'); }); }); + + describe('Common', () => { + it('Should revert when setName is called for reverse registration', async () => { + const randomEnsContract = randomAddress(); + const randomEnsName = 'random.eth'; + const txs = [ + appRegistryAsAdmin.setName(randomEnsContract, randomEnsName), + datasetRegistryAsAdmin.setName(randomEnsContract, randomEnsName), + workerpoolRegistryAsAdmin.setName(randomEnsContract, randomEnsName), + ]; + await Promise.all( + txs.map((tx) => + expect(tx).to.be.revertedWith('Operation not supported on this chain'), + ), + ); + }); + }); }); diff --git a/test/utils/utils.ts b/test/utils/utils.ts index 380fa8a73..c46ba5001 100644 --- a/test/utils/utils.ts +++ b/test/utils/utils.ts @@ -26,3 +26,7 @@ export async function setZeroAddressBalance() { ethers.toBeHex(ethers.parseEther(amount.toString())), ]); } + +export function randomAddress() { + return ethers.Wallet.createRandom().address; +}