From 0d08e6b1fb21c4972435fdf7f6fbda6fa2b3d060 Mon Sep 17 00:00:00 2001 From: "Michael D. Norman" Date: Mon, 19 Oct 2020 07:58:52 -0500 Subject: [PATCH 1/2] refactor: [#13] extract logic into libraries and include base contracts to ensure order for upgrades BREAKING CHANGE: storage locations could have changed for any of these contracts, which means old contracts cannot be safely upgraded. --- contracts/consumables/Paypr.sol | 21 +++++-- contracts/consumables/TestStableCoin.sol | 2 +- contracts/core/BaseContract.sol | 8 +-- contracts/core/Disableable.sol | 39 ++---------- contracts/core/IBaseContract.sol | 6 ++ contracts/core/IDisableable.sol | 59 +++++++++++++++++++ contracts/core/access/ConfigurableRoles.sol | 2 +- contracts/core/access/DelegatingRoles.sol | 2 +- contracts/core/access/Roles.sol | 2 +- contracts/core/account/Account.sol | 20 +++++-- contracts/core/activity/Activity.sol | 25 +++++--- .../core/activity/ConfigurableActivity.sol | 9 ++- .../ConfigurableExchangingActivity.sol | 15 ++++- ...ableSkillConstrainedExchangingActivity.sol | 17 +++++- .../core/activity/ExchangingActivity.sol | 1 - .../consumable/ConfigurableConsumable.sol | 8 ++- .../ConfigurableConvertibleConsumable.sol | 14 ++++- .../ConfigurableLimitedConsumable.sol | 14 ++++- contracts/core/consumable/Consumable.sol | 30 ++++++++-- .../consumable/TestConsumableExchange.sol | 8 ++- contracts/core/item/Artifact.sol | 25 ++++++-- contracts/core/item/ConfigurableArtifact.sol | 9 ++- .../item/{ItemUser.sol => ItemUserLogic.sol} | 11 ++-- contracts/core/player/Player.sol | 26 +++++--- .../skill/ConfigurableConstrainedSkill.sol | 15 ++++- contracts/core/skill/ConfigurableSkill.sol | 9 ++- contracts/core/skill/ConstrainedSkill.sol | 9 ++- contracts/core/skill/Skill.sol | 26 +++++++- contracts/core/skill/SkillConstrained.sol | 2 +- contracts/core/transfer/ITransferring.sol | 3 +- .../core/transfer/TestExchangingTransfer.sol | 20 +++++-- contracts/core/transfer/TestTransfer.sol | 20 +++++-- ...BaseTransferring.sol => TransferLogic.sol} | 22 +++---- 33 files changed, 360 insertions(+), 139 deletions(-) create mode 100644 contracts/core/IDisableable.sol rename contracts/core/item/{ItemUser.sol => ItemUserLogic.sol} (79%) rename contracts/core/transfer/{BaseTransferring.sol => TransferLogic.sol} (84%) diff --git a/contracts/consumables/Paypr.sol b/contracts/consumables/Paypr.sol index 8d1285ca..cba88e66 100644 --- a/contracts/consumables/Paypr.sol +++ b/contracts/consumables/Paypr.sol @@ -14,8 +14,19 @@ import '../core/consumable/ConsumableExchange.sol'; import '../core/consumable/ConvertibleConsumable.sol'; import '../core/access/DelegatingRoles.sol'; -contract Paypr is ConvertibleConsumable, ConsumableExchange, DelegatingRoles { +contract Paypr is + Initializable, + ContextUpgradeSafe, + ERC165UpgradeSafe, + BaseContract, + Consumable, + ConvertibleConsumable, + ConsumableExchange, + Disableable, + DelegatingRoles +{ using SafeMath for uint256; + using TransferLogic for address; function initializePaypr( IConsumableExchange baseToken, @@ -77,8 +88,8 @@ contract Paypr is ConvertibleConsumable, ConsumableExchange, DelegatingRoles { address sender, address recipient, uint256 amount - ) internal override(ConsumableExchange, ConvertibleConsumable) onlyEnabled { - ConsumableExchange._transfer(sender, recipient, amount); + ) internal override(Consumable, ConsumableExchange, ConvertibleConsumable) onlyEnabled { + ConvertibleConsumable._transfer(sender, recipient, amount); } function transferToken( @@ -86,7 +97,7 @@ contract Paypr is ConvertibleConsumable, ConsumableExchange, DelegatingRoles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -94,7 +105,7 @@ contract Paypr is ConvertibleConsumable, ConsumableExchange, DelegatingRoles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/consumables/TestStableCoin.sol b/contracts/consumables/TestStableCoin.sol index c929161f..e98f051f 100644 --- a/contracts/consumables/TestStableCoin.sol +++ b/contracts/consumables/TestStableCoin.sol @@ -24,7 +24,7 @@ pragma solidity ^0.6.0; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol'; import '../core/access/Roles.sol'; -contract TestStableCoin is ERC20UpgradeSafe, Roles { +contract TestStableCoin is Initializable, ContextUpgradeSafe, ERC20UpgradeSafe, AccessControlUpgradeSafe, Roles { function initialize() external initializer { __ERC20_init('MyStableCoin', 'MSC'); diff --git a/contracts/core/BaseContract.sol b/contracts/core/BaseContract.sol index 4bc69741..9801e804 100644 --- a/contracts/core/BaseContract.sol +++ b/contracts/core/BaseContract.sol @@ -26,13 +26,7 @@ import '@openzeppelin/contracts-ethereum-package/contracts/introspection/ERC165. import './IBaseContract.sol'; import './BaseContractInterfaceSupport.sol'; -contract BaseContract is IBaseContract, ERC165UpgradeSafe { - struct ContractInfo { - string name; - string description; - string uri; - } - +contract BaseContract is Initializable, IBaseContract, ERC165UpgradeSafe { ContractInfo private _info; function _initializeBaseContract(ContractInfo memory info) internal initializer { diff --git a/contracts/core/Disableable.sol b/contracts/core/Disableable.sol index c8d5fba8..c4a78c57 100644 --- a/contracts/core/Disableable.sol +++ b/contracts/core/Disableable.sol @@ -21,33 +21,19 @@ pragma solidity ^0.6.0; -abstract contract Disableable { +import './IDisableable.sol'; + +abstract contract Disableable is IDisableable { bool private _disabled; - /** - * @dev Returns whether or not the contract is disabled - */ - function disabled() external view returns (bool) { + function disabled() external override view returns (bool) { return _disabled; } - /** - * @dev Returns whether or not the contract is enabled - */ - function enabled() external view returns (bool) { + function enabled() external override view returns (bool) { return !_disabled; } - modifier onlyEnabled() { - require(!_disabled, 'Contract is disabled'); - _; - } - - /** - * @dev Disables the contract - */ - function disable() external virtual; - /** * @dev Disables the contract */ @@ -60,11 +46,6 @@ abstract contract Disableable { emit Disabled(); } - /** - * @dev Enables the contract - */ - function enable() external virtual; - /** * @dev Enables the contract */ @@ -77,15 +58,5 @@ abstract contract Disableable { emit Enabled(); } - /** - * Emitted when the contract is disabled - */ - event Disabled(); - - /** - * Emitted when the contract is enabled - */ - event Enabled(); - uint256[50] private ______gap; } diff --git a/contracts/core/IBaseContract.sol b/contracts/core/IBaseContract.sol index dc9c8144..4cb875c1 100644 --- a/contracts/core/IBaseContract.sol +++ b/contracts/core/IBaseContract.sol @@ -24,6 +24,12 @@ pragma solidity ^0.6.0; import '@openzeppelin/contracts-ethereum-package/contracts/introspection/IERC165.sol'; interface IBaseContract is IERC165 { + struct ContractInfo { + string name; + string description; + string uri; + } + function contractName() external view returns (string memory); function contractDescription() external view returns (string memory); diff --git a/contracts/core/IDisableable.sol b/contracts/core/IDisableable.sol new file mode 100644 index 00000000..ce2893c4 --- /dev/null +++ b/contracts/core/IDisableable.sol @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 The Paypr Company + * + * This file is part of Paypr Ethereum Contracts. + * + * Paypr Ethereum Contracts is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Paypr Ethereum Contracts is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Paypr Ethereum Contracts. If not, see . + */ + +// SPDX-License-Identifier: GPL-3.0-only + +pragma solidity ^0.6.0; + +interface IDisableable { + /** + * Emitted when the contract is disabled + */ + event Disabled(); + + /** + * Emitted when the contract is enabled + */ + event Enabled(); + + /** + * @dev Returns whether or not the contract is disabled + */ + function disabled() external view returns (bool); + + /** + * @dev Returns whether or not the contract is enabled + */ + function enabled() external view returns (bool); + + modifier onlyEnabled() virtual { + require(!this.disabled(), 'Contract is disabled'); + _; + } + + /** + * @dev Disables the contract + */ + function disable() external; + + /** + * @dev Enables the contract + */ + function enable() external; +} diff --git a/contracts/core/access/ConfigurableRoles.sol b/contracts/core/access/ConfigurableRoles.sol index d3153f17..2af0f7dd 100644 --- a/contracts/core/access/ConfigurableRoles.sol +++ b/contracts/core/access/ConfigurableRoles.sol @@ -27,7 +27,7 @@ import '@openzeppelin/contracts-ethereum-package/contracts/introspection/ERC165. import './Roles.sol'; import './RoleDelegateInterfaceSupport.sol'; -contract ConfigurableRoles is Roles, ERC165UpgradeSafe { +contract ConfigurableRoles is Initializable, ContextUpgradeSafe, ERC165UpgradeSafe, Roles { function initializeRoles(IRoleDelegate roleDelegate) public initializer { __ERC165_init(); _registerInterface(RoleDelegateInterfaceSupport.ROLE_DELEGATE_INTERFACE_ID); diff --git a/contracts/core/access/DelegatingRoles.sol b/contracts/core/access/DelegatingRoles.sol index 811b92ad..568eff1c 100644 --- a/contracts/core/access/DelegatingRoles.sol +++ b/contracts/core/access/DelegatingRoles.sol @@ -27,7 +27,7 @@ import './IRoleDelegate.sol'; import './RoleDelegateInterfaceSupport.sol'; import './RoleSupport.sol'; -contract DelegatingRoles is ContextUpgradeSafe { +contract DelegatingRoles is Initializable, ContextUpgradeSafe { using EnumerableSet for EnumerableSet.AddressSet; using RoleDelegateInterfaceSupport for IRoleDelegate; diff --git a/contracts/core/access/Roles.sol b/contracts/core/access/Roles.sol index 93aee187..c7fb0d00 100644 --- a/contracts/core/access/Roles.sol +++ b/contracts/core/access/Roles.sol @@ -26,7 +26,7 @@ import './DelegatingRoles.sol'; import './IRoleDelegate.sol'; import './RoleSupport.sol'; -contract Roles is IRoleDelegate, DelegatingRoles, AccessControlUpgradeSafe { +contract Roles is IRoleDelegate, Initializable, ContextUpgradeSafe, AccessControlUpgradeSafe, DelegatingRoles { function _initializeRoles(IRoleDelegate roleDelegate) public initializer { if (address(roleDelegate) != address(0)) { _addRoleDelegate(roleDelegate); diff --git a/contracts/core/account/Account.sol b/contracts/core/account/Account.sol index 7d7cc4aa..95f7b5c4 100644 --- a/contracts/core/account/Account.sol +++ b/contracts/core/account/Account.sol @@ -26,13 +26,16 @@ import '@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol'; import '@openzeppelin/contracts-ethereum-package/contracts/introspection/ERC165.sol'; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/IERC721.sol'; -import '../transfer/BaseTransferring.sol'; import '../transfer/TransferringInterfaceSupport.sol'; import '../Disableable.sol'; import '../access/Roles.sol'; import '../access/RoleDelegateInterfaceSupport.sol'; +import '../transfer/ITransferring.sol'; +import '../transfer/TransferLogic.sol'; + +contract Account is Initializable, ITransferring, ContextUpgradeSafe, ERC165UpgradeSafe, Disableable, Roles { + using TransferLogic for address; -contract Account is BaseTransferring, Roles, ERC165UpgradeSafe, Disableable { function initializeAccount(IRoleDelegate roleDelegate) public initializer { __ERC165_init(); _registerInterface(RoleDelegateInterfaceSupport.ROLE_DELEGATE_INTERFACE_ID); @@ -52,7 +55,7 @@ contract Account is BaseTransferring, Roles, ERC165UpgradeSafe, Disableable { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferTokenWithExchange(token, amount, recipient); + address(this).transferTokenWithExchange(token, amount, recipient); } function transferItem( @@ -60,7 +63,16 @@ contract Account is BaseTransferring, Roles, ERC165UpgradeSafe, Disableable { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); + } + + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external virtual override returns (bytes4) { + return TransferLogic.onERC721Received(operator, from, tokenId, data); } function disable() external override onlyAdmin { diff --git a/contracts/core/activity/Activity.sol b/contracts/core/activity/Activity.sol index 85fd83d7..9a96cc9a 100644 --- a/contracts/core/activity/Activity.sol +++ b/contracts/core/activity/Activity.sol @@ -31,22 +31,24 @@ import '../consumable/ConsumableConsumerInterfaceSupport.sol'; import '../consumable/ConsumableProvider.sol'; import '../consumable/ConsumableProviderInterfaceSupport.sol'; import '../BaseContract.sol'; -import '../item/ItemUser.sol'; -import '../Disableable.sol'; -import '../transfer/BaseTransferring.sol'; +import '../IDisableable.sol'; import '../transfer/TransferringInterfaceSupport.sol'; +import '../transfer/ITransferring.sol'; +import '../transfer/TransferLogic.sol'; abstract contract Activity is + IDisableable, + Initializable, + ITransferring, IActivity, ContextUpgradeSafe, + ERC165UpgradeSafe, BaseContract, - BaseTransferring, - Disableable, ConsumableConsumer, - ConsumableProvider, - ItemUser + ConsumableProvider { using Counters for Counters.Counter; + using TransferLogic for address; mapping(address => Counters.Counter) private _executed; Counters.Counter private _totalExecuted; @@ -101,5 +103,14 @@ abstract contract Activity is // does nothing by default } + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external virtual override returns (bytes4) { + return TransferLogic.onERC721Received(operator, from, tokenId, data); + } + uint256[50] private ______gap; } diff --git a/contracts/core/activity/ConfigurableActivity.sol b/contracts/core/activity/ConfigurableActivity.sol index 11fb62e3..29233629 100644 --- a/contracts/core/activity/ConfigurableActivity.sol +++ b/contracts/core/activity/ConfigurableActivity.sol @@ -24,8 +24,11 @@ pragma experimental ABIEncoderV2; import './Activity.sol'; import '../access/DelegatingRoles.sol'; +import '../Disableable.sol'; + +contract ConfigurableActivity is Initializable, ContextUpgradeSafe, Activity, Disableable, DelegatingRoles { + using TransferLogic for address; -contract ConfigurableActivity is Activity, DelegatingRoles { function initializeActivity( ContractInfo memory info, IConsumable.ConsumableAmount[] memory amountsToConsume, @@ -42,7 +45,7 @@ contract ConfigurableActivity is Activity, DelegatingRoles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -50,7 +53,7 @@ contract ConfigurableActivity is Activity, DelegatingRoles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/core/activity/ConfigurableExchangingActivity.sol b/contracts/core/activity/ConfigurableExchangingActivity.sol index 20b43938..f5a0b486 100644 --- a/contracts/core/activity/ConfigurableExchangingActivity.sol +++ b/contracts/core/activity/ConfigurableExchangingActivity.sol @@ -24,8 +24,17 @@ pragma experimental ABIEncoderV2; import './ExchangingActivity.sol'; import '../access/DelegatingRoles.sol'; +import '../Disableable.sol'; + +contract ConfigurableExchangingActivity is + Initializable, + ContextUpgradeSafe, + ExchangingActivity, + Disableable, + DelegatingRoles +{ + using TransferLogic for address; -contract ConfigurableExchangingActivity is ExchangingActivity, DelegatingRoles { function initializeExchangingActivity( ContractInfo memory info, IConsumable.ConsumableAmount[] memory amountsToConsume, @@ -43,7 +52,7 @@ contract ConfigurableExchangingActivity is ExchangingActivity, DelegatingRoles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -51,7 +60,7 @@ contract ConfigurableExchangingActivity is ExchangingActivity, DelegatingRoles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/core/activity/ConfigurableSkillConstrainedExchangingActivity.sol b/contracts/core/activity/ConfigurableSkillConstrainedExchangingActivity.sol index b645fd48..152fec8f 100644 --- a/contracts/core/activity/ConfigurableSkillConstrainedExchangingActivity.sol +++ b/contracts/core/activity/ConfigurableSkillConstrainedExchangingActivity.sol @@ -25,8 +25,19 @@ pragma experimental ABIEncoderV2; import './ExchangingActivity.sol'; import '../skill/SkillConstrained.sol'; import '../access/DelegatingRoles.sol'; +import '../Disableable.sol'; + +contract ConfigurableSkillConstrainedExchangingActivity is + Initializable, + ContextUpgradeSafe, + ERC165UpgradeSafe, + ExchangingActivity, + SkillConstrained, + Disableable, + DelegatingRoles +{ + using TransferLogic for address; -contract ConfigurableSkillConstrainedExchangingActivity is SkillConstrained, ExchangingActivity, DelegatingRoles { function initializeSkillConstrainedExchangingActivity( ContractInfo memory info, SkillLevel[] memory requiredSkillLevels, @@ -47,7 +58,7 @@ contract ConfigurableSkillConstrainedExchangingActivity is SkillConstrained, Exc uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -55,7 +66,7 @@ contract ConfigurableSkillConstrainedExchangingActivity is SkillConstrained, Exc uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function _checkRequirements(address player) internal override view { diff --git a/contracts/core/activity/ExchangingActivity.sol b/contracts/core/activity/ExchangingActivity.sol index 4eecacc8..cfc42832 100644 --- a/contracts/core/activity/ExchangingActivity.sol +++ b/contracts/core/activity/ExchangingActivity.sol @@ -27,7 +27,6 @@ import './Activity.sol'; import '../consumable/ConsumableExchangeInterfaceSupport.sol'; import '../consumable/IConsumableExchange.sol'; import '../consumable/IConvertibleConsumable.sol'; -import '../consumable/ConsumableExchange.sol'; import '../consumable/ConsumableConversionMath.sol'; abstract contract ExchangingActivity is Activity { diff --git a/contracts/core/consumable/ConfigurableConsumable.sol b/contracts/core/consumable/ConfigurableConsumable.sol index efc5aa0b..a7684f4a 100644 --- a/contracts/core/consumable/ConfigurableConsumable.sol +++ b/contracts/core/consumable/ConfigurableConsumable.sol @@ -25,7 +25,9 @@ pragma experimental ABIEncoderV2; import './Consumable.sol'; import '../access/DelegatingRoles.sol'; -contract ConfigurableConsumable is Consumable, DelegatingRoles { +contract ConfigurableConsumable is Initializable, ContextUpgradeSafe, Consumable, Disableable, DelegatingRoles { + using TransferLogic for address; + function initializeConsumable( ContractInfo memory info, string memory symbol, @@ -61,7 +63,7 @@ contract ConfigurableConsumable is Consumable, DelegatingRoles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -69,7 +71,7 @@ contract ConfigurableConsumable is Consumable, DelegatingRoles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/core/consumable/ConfigurableConvertibleConsumable.sol b/contracts/core/consumable/ConfigurableConvertibleConsumable.sol index 1d402a0c..795b9a87 100644 --- a/contracts/core/consumable/ConfigurableConvertibleConsumable.sol +++ b/contracts/core/consumable/ConfigurableConvertibleConsumable.sol @@ -25,7 +25,15 @@ pragma experimental ABIEncoderV2; import './ConvertibleConsumable.sol'; import '../access/DelegatingRoles.sol'; -contract ConfigurableConvertibleConsumable is ConvertibleConsumable, DelegatingRoles { +contract ConfigurableConvertibleConsumable is + Initializable, + ContextUpgradeSafe, + ConvertibleConsumable, + Disableable, + DelegatingRoles +{ + using TransferLogic for address; + function initializeConvertibleConsumable( ContractInfo memory info, string memory symbol, @@ -79,7 +87,7 @@ contract ConfigurableConvertibleConsumable is ConvertibleConsumable, DelegatingR uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -87,7 +95,7 @@ contract ConfigurableConvertibleConsumable is ConvertibleConsumable, DelegatingR uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/core/consumable/ConfigurableLimitedConsumable.sol b/contracts/core/consumable/ConfigurableLimitedConsumable.sol index ba2c56c0..cba9f0bc 100644 --- a/contracts/core/consumable/ConfigurableLimitedConsumable.sol +++ b/contracts/core/consumable/ConfigurableLimitedConsumable.sol @@ -25,7 +25,15 @@ pragma experimental ABIEncoderV2; import './LimitedConsumable.sol'; import '../access/DelegatingRoles.sol'; -contract ConfigurableLimitedConsumable is LimitedConsumable, DelegatingRoles { +contract ConfigurableLimitedConsumable is + Initializable, + ContextUpgradeSafe, + LimitedConsumable, + Disableable, + DelegatingRoles +{ + using TransferLogic for address; + function initializeLimitedConsumable( ContractInfo memory info, string memory symbol, @@ -79,7 +87,7 @@ contract ConfigurableLimitedConsumable is LimitedConsumable, DelegatingRoles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -87,7 +95,7 @@ contract ConfigurableLimitedConsumable is LimitedConsumable, DelegatingRoles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/core/consumable/Consumable.sol b/contracts/core/consumable/Consumable.sol index 74ed57c6..2b1480bc 100644 --- a/contracts/core/consumable/Consumable.sol +++ b/contracts/core/consumable/Consumable.sol @@ -22,15 +22,28 @@ pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; +import '@openzeppelin/contracts-ethereum-package/contracts/introspection/ERC165.sol'; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol'; -import '../BaseContract.sol'; -import '../Disableable.sol'; import './ConsumableInterfaceSupport.sol'; import './IConsumable.sol'; -import '../transfer/BaseTransferring.sol'; +import '../BaseContract.sol'; +import '../Disableable.sol'; import '../transfer/TransferringInterfaceSupport.sol'; +import '../transfer/ITransferring.sol'; +import '../transfer/TransferLogic.sol'; + +abstract contract Consumable is + IDisableable, + Initializable, + ITransferring, + ContextUpgradeSafe, + IConsumable, + ERC165UpgradeSafe, + BaseContract, + ERC20UpgradeSafe +{ + using TransferLogic for address; -abstract contract Consumable is IConsumable, BaseContract, BaseTransferring, ERC20UpgradeSafe, Disableable { function _initializeConsumable(ContractInfo memory info, string memory symbol) internal initializer { _initializeBaseContract(info); _registerInterface(ConsumableInterfaceSupport.CONSUMABLE_INTERFACE_ID); @@ -55,5 +68,14 @@ abstract contract Consumable is IConsumable, BaseContract, BaseTransferring, ERC super._transfer(sender, recipient, amount); } + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external virtual override returns (bytes4) { + return TransferLogic.onERC721Received(operator, from, tokenId, data); + } + uint256[50] private ______gap; } diff --git a/contracts/core/consumable/TestConsumableExchange.sol b/contracts/core/consumable/TestConsumableExchange.sol index 4396c542..58deb5bd 100644 --- a/contracts/core/consumable/TestConsumableExchange.sol +++ b/contracts/core/consumable/TestConsumableExchange.sol @@ -25,7 +25,9 @@ pragma experimental ABIEncoderV2; import './ConsumableExchange.sol'; import '../access/Roles.sol'; -contract TestConsumableExchange is ConsumableExchange, Roles { +contract TestConsumableExchange is ConsumableExchange, Disableable, Roles { + using TransferLogic for address; + function initializeConsumableExchange(ContractInfo memory info, string memory symbol) public initializer { _initializeConsumableExchange(info, symbol); @@ -40,7 +42,7 @@ contract TestConsumableExchange is ConsumableExchange, Roles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -48,7 +50,7 @@ contract TestConsumableExchange is ConsumableExchange, Roles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } /** diff --git a/contracts/core/item/Artifact.sol b/contracts/core/item/Artifact.sol index cbb2c4a8..ec1bc59f 100644 --- a/contracts/core/item/Artifact.sol +++ b/contracts/core/item/Artifact.sol @@ -27,18 +27,24 @@ import './ArtifactInterfaceSupport.sol'; import './IArtifact.sol'; import '../consumable/ConsumableProvider.sol'; import '../consumable/ConsumableProviderInterfaceSupport.sol'; -import '../Disableable.sol'; -import '../transfer/BaseTransferring.sol'; +import '../IDisableable.sol'; import '../transfer/TransferringInterfaceSupport.sol'; +import '../transfer/TransferLogic.sol'; +import '../transfer/ITransferring.sol'; abstract contract Artifact is + IDisableable, + Initializable, + ContextUpgradeSafe, + ITransferring, + ERC165UpgradeSafe, IArtifact, BaseContract, - BaseTransferring, ConsumableProvider, - ERC721UpgradeSafe, - Disableable + ERC721UpgradeSafe { + using TransferLogic for address; + uint256 private _initialUses; mapping(uint256 => uint256) private _usesLeft; @@ -102,5 +108,14 @@ abstract contract Artifact is require(_canProvideMultiple(_totalUsesLeft), 'Artifact: not enough consumable for items'); } + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external virtual override returns (bytes4) { + return TransferLogic.onERC721Received(operator, from, tokenId, data); + } + uint256[50] private ______gap; } diff --git a/contracts/core/item/ConfigurableArtifact.sol b/contracts/core/item/ConfigurableArtifact.sol index 1bdf3c34..369e875c 100644 --- a/contracts/core/item/ConfigurableArtifact.sol +++ b/contracts/core/item/ConfigurableArtifact.sol @@ -25,8 +25,11 @@ pragma experimental ABIEncoderV2; import '@openzeppelin/contracts-ethereum-package/contracts/utils/Counters.sol'; import './Artifact.sol'; import '../access/DelegatingRoles.sol'; +import '../Disableable.sol'; + +contract ConfigurableArtifact is Initializable, ContextUpgradeSafe, Artifact, Disableable, DelegatingRoles { + using TransferLogic for address; -contract ConfigurableArtifact is Artifact, DelegatingRoles { using Counters for Counters.Counter; Counters.Counter private _lastItemId; @@ -58,7 +61,7 @@ contract ConfigurableArtifact is Artifact, DelegatingRoles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); _checkEnoughConsumable(); } @@ -67,7 +70,7 @@ contract ConfigurableArtifact is Artifact, DelegatingRoles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/core/item/ItemUser.sol b/contracts/core/item/ItemUserLogic.sol similarity index 79% rename from contracts/core/item/ItemUser.sol rename to contracts/core/item/ItemUserLogic.sol index 01a06221..a88131a2 100644 --- a/contracts/core/item/ItemUser.sol +++ b/contracts/core/item/ItemUserLogic.sol @@ -20,22 +20,19 @@ // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.6.0; -pragma experimental ABIEncoderV2; import './IArtifact.sol'; import './ArtifactInterfaceSupport.sol'; -abstract contract ItemUser { +library ItemUserLogic { using ArtifactInterfaceSupport for IArtifact; - function _useItems(IArtifact.Item[] memory useItems, address action) internal { - for (uint256 itemIndex = 0; itemIndex < useItems.length; itemIndex++) { - IArtifact.Item memory item = useItems[itemIndex]; + function useItems(address action, IArtifact.Item[] memory itemsToUse) internal { + for (uint256 itemIndex = 0; itemIndex < itemsToUse.length; itemIndex++) { + IArtifact.Item memory item = itemsToUse[itemIndex]; IArtifact artifact = item.artifact; require(artifact.supportsArtifactInterface(), 'ItemUser: item address must support IArtifact'); artifact.useItem(item.itemId, action); } } - - uint256[50] private ______gap; } diff --git a/contracts/core/player/Player.sol b/contracts/core/player/Player.sol index c7554e79..cfaccdc6 100644 --- a/contracts/core/player/Player.sol +++ b/contracts/core/player/Player.sol @@ -30,22 +30,25 @@ import '../activity/IActivity.sol'; import '../consumable/ConsumableInterfaceSupport.sol'; import '../consumable/ConvertibleConsumableInterfaceSupport.sol'; import '../consumable/IConvertibleConsumable.sol'; -import '../item/ItemUser.sol'; import '../access/Roles.sol'; import '../skill/ISkill.sol'; import '../skill/SkillInterfaceSupport.sol'; import './IPlayer.sol'; import './PlayerInterfaceSupport.sol'; import '../Disableable.sol'; -import '../transfer/BaseTransferring.sol'; import '../transfer/TransferringInterfaceSupport.sol'; +import '../transfer/ITransferring.sol'; +import '../transfer/TransferLogic.sol'; +import '../item/ItemUserLogic.sol'; -contract Player is IPlayer, BaseTransferring, Roles, ERC165UpgradeSafe, Disableable, ItemUser { +contract Player is Initializable, ITransferring, IPlayer, ContextUpgradeSafe, ERC165UpgradeSafe, Disableable, Roles { using ActivityInterfaceSupport for IActivity; using ConsumableInterfaceSupport for IConsumable; using ConvertibleConsumableInterfaceSupport for IConvertibleConsumable; using PlayerInterfaceSupport for IPlayer; using SkillInterfaceSupport for ISkill; + using TransferLogic for address; + using ItemUserLogic for address; function initializePlayer(IRoleDelegate roleDelegate) public initializer { __ERC165_init(); @@ -70,7 +73,7 @@ contract Player is IPlayer, BaseTransferring, Roles, ERC165UpgradeSafe, Disablea ) external override onlyEnabled onlyAdmin { require(activity.supportsActivityInterface(), 'Player: activity address must support IActivity'); - _useItems(useItems, address(activity)); + address(activity).useItems(useItems); _provideConsumables(address(activity), amountsToProvide); @@ -91,7 +94,7 @@ contract Player is IPlayer, BaseTransferring, Roles, ERC165UpgradeSafe, Disablea ) external override onlyEnabled onlyAdmin { require(skill.supportsSkillInterface(), 'Player: skill address must support ISkill'); - _useItems(useItems, address(skill)); + address(skill).useItems(useItems); _provideConsumables(address(skill), amountsToProvide); @@ -133,7 +136,7 @@ contract Player is IPlayer, BaseTransferring, Roles, ERC165UpgradeSafe, Disablea uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferTokenWithExchange(token, amount, recipient); + address(this).transferTokenWithExchange(token, amount, recipient); } function transferItem( @@ -141,7 +144,16 @@ contract Player is IPlayer, BaseTransferring, Roles, ERC165UpgradeSafe, Disablea uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); + } + + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external virtual override returns (bytes4) { + return TransferLogic.onERC721Received(operator, from, tokenId, data); } function disable() external override onlyAdmin { diff --git a/contracts/core/skill/ConfigurableConstrainedSkill.sol b/contracts/core/skill/ConfigurableConstrainedSkill.sol index f9338159..64bf9c02 100644 --- a/contracts/core/skill/ConfigurableConstrainedSkill.sol +++ b/contracts/core/skill/ConfigurableConstrainedSkill.sol @@ -24,8 +24,17 @@ pragma experimental ABIEncoderV2; import './ConstrainedSkill.sol'; import '../access/DelegatingRoles.sol'; +import '../Disableable.sol'; + +contract ConfigurableConstrainedSkill is + Initializable, + ContextUpgradeSafe, + ConstrainedSkill, + Disableable, + DelegatingRoles +{ + using TransferLogic for address; -contract ConfigurableConstrainedSkill is ConstrainedSkill, DelegatingRoles { function initializeConstrainedSkill( ContractInfo memory info, IConsumable.ConsumableAmount[] memory amountsToConsume, @@ -43,7 +52,7 @@ contract ConfigurableConstrainedSkill is ConstrainedSkill, DelegatingRoles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -51,7 +60,7 @@ contract ConfigurableConstrainedSkill is ConstrainedSkill, DelegatingRoles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/core/skill/ConfigurableSkill.sol b/contracts/core/skill/ConfigurableSkill.sol index 989fa5c6..b387be57 100644 --- a/contracts/core/skill/ConfigurableSkill.sol +++ b/contracts/core/skill/ConfigurableSkill.sol @@ -24,8 +24,11 @@ pragma experimental ABIEncoderV2; import './Skill.sol'; import '../access/DelegatingRoles.sol'; +import '../Disableable.sol'; + +contract ConfigurableSkill is Initializable, ContextUpgradeSafe, Skill, Disableable, DelegatingRoles { + using TransferLogic for address; -contract ConfigurableSkill is Skill, DelegatingRoles { function initializeSkill(ContractInfo memory info, IRoleDelegate roleDelegate) public initializer { _initializeSkill(info); @@ -37,7 +40,7 @@ contract ConfigurableSkill is Skill, DelegatingRoles { uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -45,7 +48,7 @@ contract ConfigurableSkill is Skill, DelegatingRoles { uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); } function disable() external override onlyAdmin { diff --git a/contracts/core/skill/ConstrainedSkill.sol b/contracts/core/skill/ConstrainedSkill.sol index 7968e999..50d611aa 100644 --- a/contracts/core/skill/ConstrainedSkill.sol +++ b/contracts/core/skill/ConstrainedSkill.sol @@ -27,7 +27,14 @@ import './Skill.sol'; import '../consumable/ConsumableConsumer.sol'; import '../consumable/ConsumableConsumerInterfaceSupport.sol'; -abstract contract ConstrainedSkill is Skill, SkillConstrained, ConsumableConsumer { +abstract contract ConstrainedSkill is + Initializable, + ContextUpgradeSafe, + ERC165UpgradeSafe, + Skill, + SkillConstrained, + ConsumableConsumer +{ using ConsumableInterfaceSupport for IConsumable; function _initializeConstrainedSkill(ContractInfo memory info, IConsumable.ConsumableAmount[] memory amountsToConsume) diff --git a/contracts/core/skill/Skill.sol b/contracts/core/skill/Skill.sol index 8752e13c..3c64655e 100644 --- a/contracts/core/skill/Skill.sol +++ b/contracts/core/skill/Skill.sol @@ -26,11 +26,22 @@ import '@openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol'; import '../BaseContract.sol'; import './ISkill.sol'; import './SkillInterfaceSupport.sol'; -import '../Disableable.sol'; -import '../transfer/BaseTransferring.sol'; +import '../IDisableable.sol'; import '../transfer/TransferringInterfaceSupport.sol'; +import '../transfer/ITransferring.sol'; +import '../transfer/TransferLogic.sol'; + +abstract contract Skill is + IDisableable, + Initializable, + ITransferring, + ISkill, + ContextUpgradeSafe, + ERC165UpgradeSafe, + BaseContract +{ + using TransferLogic for address; -abstract contract Skill is ISkill, ContextUpgradeSafe, BaseContract, BaseTransferring, Disableable { mapping(address => uint256) private _levels; function _initializeSkill(ContractInfo memory info) internal initializer { @@ -86,5 +97,14 @@ abstract contract Skill is ISkill, ContextUpgradeSafe, BaseContract, BaseTransfe require(level == _levels[player] + 1, 'Skill: acquire invalid level'); } + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external virtual override returns (bytes4) { + return TransferLogic.onERC721Received(operator, from, tokenId, data); + } + uint256[50] private ______gap; } diff --git a/contracts/core/skill/SkillConstrained.sol b/contracts/core/skill/SkillConstrained.sol index 02f726b8..a95774b6 100644 --- a/contracts/core/skill/SkillConstrained.sol +++ b/contracts/core/skill/SkillConstrained.sol @@ -27,7 +27,7 @@ import './ISkillConstrained.sol'; import './SkillConstrainedInterfaceSupport.sol'; import './SkillInterfaceSupport.sol'; -contract SkillConstrained is ISkillConstrained, ERC165UpgradeSafe { +contract SkillConstrained is Initializable, ISkillConstrained, ERC165UpgradeSafe { using SkillInterfaceSupport for ISkill; struct SkillLevel { diff --git a/contracts/core/transfer/ITransferring.sol b/contracts/core/transfer/ITransferring.sol index d44f0344..46d5ddde 100644 --- a/contracts/core/transfer/ITransferring.sol +++ b/contracts/core/transfer/ITransferring.sol @@ -24,8 +24,9 @@ pragma solidity ^0.6.0; import '@openzeppelin/contracts-ethereum-package/contracts/introspection/IERC165.sol'; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol'; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/IERC721.sol'; +import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/IERC721Receiver.sol'; -interface ITransferring is IERC165 { +interface ITransferring is IERC165, IERC721Receiver { /** * @dev Transfer the given amount of an ERC20 token to the given recipient address. */ diff --git a/contracts/core/transfer/TestExchangingTransfer.sol b/contracts/core/transfer/TestExchangingTransfer.sol index a0e00d32..309ed29a 100644 --- a/contracts/core/transfer/TestExchangingTransfer.sol +++ b/contracts/core/transfer/TestExchangingTransfer.sol @@ -22,12 +22,15 @@ pragma solidity ^0.6.0; import '@openzeppelin/contracts-ethereum-package/contracts/introspection/ERC165.sol'; -import './BaseTransferring.sol'; import './TransferringInterfaceSupport.sol'; import '../access/Roles.sol'; import '../Disableable.sol'; +import './ITransferring.sol'; +import './TransferLogic.sol'; + +contract TestExchangingTransfer is ITransferring, ERC165UpgradeSafe, Disableable, Roles { + using TransferLogic for address; -contract TestExchangingTransfer is BaseTransferring, ERC165UpgradeSafe, Disableable, Roles { function initializeExchangingTestTransfer() external initializer { _registerInterface(TransferringInterfaceSupport.TRANSFERRING_INTERFACE_ID); _addSuperAdmin(_msgSender()); @@ -40,7 +43,7 @@ contract TestExchangingTransfer is BaseTransferring, ERC165UpgradeSafe, Disablea uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferTokenWithExchange(token, amount, recipient); + address(this).transferTokenWithExchange(token, amount, recipient); } function transferItem( @@ -48,7 +51,16 @@ contract TestExchangingTransfer is BaseTransferring, ERC165UpgradeSafe, Disablea uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); + } + + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external virtual override returns (bytes4) { + return TransferLogic.onERC721Received(operator, from, tokenId, data); } function disable() external override onlyAdmin { diff --git a/contracts/core/transfer/TestTransfer.sol b/contracts/core/transfer/TestTransfer.sol index 5ac49ba5..203effbf 100644 --- a/contracts/core/transfer/TestTransfer.sol +++ b/contracts/core/transfer/TestTransfer.sol @@ -22,12 +22,15 @@ pragma solidity ^0.6.0; import '@openzeppelin/contracts-ethereum-package/contracts/introspection/ERC165.sol'; -import './BaseTransferring.sol'; import './TransferringInterfaceSupport.sol'; import '../access/Roles.sol'; import '../Disableable.sol'; +import './ITransferring.sol'; +import './TransferLogic.sol'; + +contract TestTransfer is ITransferring, ERC165UpgradeSafe, Disableable, Roles { + using TransferLogic for address; -contract TestTransfer is BaseTransferring, ERC165UpgradeSafe, Disableable, Roles { function initializeTestTransfer() external initializer { _registerInterface(TransferringInterfaceSupport.TRANSFERRING_INTERFACE_ID); _addSuperAdmin(_msgSender()); @@ -40,7 +43,7 @@ contract TestTransfer is BaseTransferring, ERC165UpgradeSafe, Disableable, Roles uint256 amount, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferToken(token, amount, recipient); + address(this).transferToken(token, amount, recipient); } function transferItem( @@ -48,7 +51,16 @@ contract TestTransfer is BaseTransferring, ERC165UpgradeSafe, Disableable, Roles uint256 itemId, address recipient ) external override onlyTransferAgent onlyEnabled { - _transferItem(artifact, itemId, recipient); + address(this).transferItem(artifact, itemId, recipient); + } + + function onERC721Received( + address operator, + address from, + uint256 tokenId, + bytes calldata data + ) external virtual override returns (bytes4) { + return TransferLogic.onERC721Received(operator, from, tokenId, data); } function disable() external override onlyAdmin { diff --git a/contracts/core/transfer/BaseTransferring.sol b/contracts/core/transfer/TransferLogic.sol similarity index 84% rename from contracts/core/transfer/BaseTransferring.sol rename to contracts/core/transfer/TransferLogic.sol index 9ebdf5cc..7ccd9a90 100644 --- a/contracts/core/transfer/BaseTransferring.sol +++ b/contracts/core/transfer/TransferLogic.sol @@ -24,14 +24,14 @@ pragma solidity ^0.6.0; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC20/ERC20.sol'; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/IERC721.sol'; import '@openzeppelin/contracts-ethereum-package/contracts/token/ERC721/IERC721Receiver.sol'; -import './ITransferring.sol'; import '../consumable/IConvertibleConsumable.sol'; import '../consumable/ConvertibleConsumableInterfaceSupport.sol'; -abstract contract BaseTransferring is ITransferring, IERC721Receiver { +library TransferLogic { using ConvertibleConsumableInterfaceSupport for IConvertibleConsumable; - function _transferToken( + function transferToken( + address, /*account*/ IERC20 token, uint256 amount, address recipient @@ -39,12 +39,13 @@ abstract contract BaseTransferring is ITransferring, IERC721Receiver { token.transfer(recipient, amount); } - function _transferTokenWithExchange( + function transferTokenWithExchange( + address account, IERC20 token, uint256 amount, address recipient ) internal { - uint256 myBalance = token.balanceOf(address(this)); + uint256 myBalance = token.balanceOf(account); if (myBalance < amount && IConvertibleConsumable(address(token)).supportsConvertibleConsumableInterface()) { // increase allowance as needed, but only if it's a convertible consumable IConvertibleConsumable convertibleConsumable = IConvertibleConsumable(address(token)); @@ -59,20 +60,21 @@ abstract contract BaseTransferring is ITransferring, IERC721Receiver { token.transfer(recipient, amount); } - function _transferItem( + function transferItem( + address account, IERC721 artifact, uint256 itemId, address recipient ) internal { - artifact.safeTransferFrom(address(this), recipient, itemId); + artifact.safeTransferFrom(account, recipient, itemId); } function onERC721Received( address, /*operator*/ address, /*from*/ uint256, /*tokenId*/ - bytes calldata /*data*/ - ) external virtual override returns (bytes4) { - return this.onERC721Received.selector; + bytes memory /*data*/ + ) internal pure returns (bytes4) { + return IERC721Receiver.onERC721Received.selector; } } From 4105c336c9a4756a6bd00836a3b459a74b778291 Mon Sep 17 00:00:00 2001 From: "Michael D. Norman" Date: Wed, 21 Oct 2020 08:49:39 -0500 Subject: [PATCH 2/2] refactor: [#13] revert moving ContractInfo to the interface until it's necessary --- contracts/core/BaseContract.sol | 6 ++++++ contracts/core/IBaseContract.sol | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/core/BaseContract.sol b/contracts/core/BaseContract.sol index 9801e804..534b2e45 100644 --- a/contracts/core/BaseContract.sol +++ b/contracts/core/BaseContract.sol @@ -27,6 +27,12 @@ import './IBaseContract.sol'; import './BaseContractInterfaceSupport.sol'; contract BaseContract is Initializable, IBaseContract, ERC165UpgradeSafe { + struct ContractInfo { + string name; + string description; + string uri; + } + ContractInfo private _info; function _initializeBaseContract(ContractInfo memory info) internal initializer { diff --git a/contracts/core/IBaseContract.sol b/contracts/core/IBaseContract.sol index 4cb875c1..dc9c8144 100644 --- a/contracts/core/IBaseContract.sol +++ b/contracts/core/IBaseContract.sol @@ -24,12 +24,6 @@ pragma solidity ^0.6.0; import '@openzeppelin/contracts-ethereum-package/contracts/introspection/IERC165.sol'; interface IBaseContract is IERC165 { - struct ContractInfo { - string name; - string description; - string uri; - } - function contractName() external view returns (string memory); function contractDescription() external view returns (string memory);