diff --git a/contracts/interfaces/ILegionMetadataStore.sol b/contracts/interfaces/ILegionMetadataStore.sol deleted file mode 100644 index 16e6d2b..0000000 --- a/contracts/interfaces/ILegionMetadataStore.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.28; - -interface ILegionMetadataStore { - // Returns the generation and rarity for the given legion. - function genAndRarityForLegion(uint256 _tokenId) external view returns (LegionGeneration, LegionRarity); -} - -enum LegionRarity { - LEGENDARY, - RARE, - SPECIAL, - UNCOMMON, - COMMON, - RECRUIT -} - -enum LegionGeneration { - GENESIS, - AUXILIARY, - RECRUIT -} diff --git a/contracts/mock/EIP173Proxy.sol b/contracts/mock/EIP173Proxy.sol deleted file mode 100644 index 441ba86..0000000 --- a/contracts/mock/EIP173Proxy.sol +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import "./Proxy.sol"; - -interface ERC165 { - function supportsInterface(bytes4 id) external view returns (bool); -} - -///@notice Proxy implementing EIP173 for ownership management -contract EIP173Proxy is Proxy { - // ////////////////////////// EVENTS /////////////////////////////////////////////////////////////////////// - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - // /////////////////////// CONSTRUCTOR ////////////////////////////////////////////////////////////////////// - - constructor(address implementationAddress, address ownerAddress, bytes memory data) payable { - _setImplementation(implementationAddress, data); - _setOwner(ownerAddress); - } - - // ///////////////////// EXTERNAL /////////////////////////////////////////////////////////////////////////// - - function owner() external view returns (address) { - return _owner(); - } - - function supportsInterface(bytes4 id) external view returns (bool) { - if (id == 0x01ffc9a7 || id == 0x7f5828d0) { - return true; - } - if (id == 0xFFFFFFFF) { - return false; - } - - ERC165 implementation; - // solhint-disable-next-line security/no-inline-assembly - assembly { - implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc) - } - - // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure - // because it is itself inside `supportsInterface` that might only get 30,000 gas. - // In practise this is unlikely to be an issue. - try implementation.supportsInterface(id) returns (bool support) { - return support; - } catch { - return false; - } - } - - function transferOwnership(address newOwner) external onlyOwner { - _setOwner(newOwner); - } - - function upgradeTo(address newImplementation) external onlyOwner { - _setImplementation(newImplementation, ""); - } - - function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner { - _setImplementation(newImplementation, data); - } - - // /////////////////////// MODIFIERS //////////////////////////////////////////////////////////////////////// - - modifier onlyOwner() { - require(msg.sender == _owner(), "NOT_AUTHORIZED"); - _; - } - - // ///////////////////////// INTERNAL ////////////////////////////////////////////////////////////////////// - - function _owner() internal view returns (address adminAddress) { - // solhint-disable-next-line security/no-inline-assembly - assembly { - adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103) - } - } - - function _setOwner(address newOwner) internal { - address previousOwner = _owner(); - // solhint-disable-next-line security/no-inline-assembly - assembly { - sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner) - } - emit OwnershipTransferred(previousOwner, newOwner); - } -} diff --git a/contracts/mock/LegionMetadataStoreMock.sol b/contracts/mock/LegionMetadataStoreMock.sol deleted file mode 100644 index d0a5337..0000000 --- a/contracts/mock/LegionMetadataStoreMock.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.28; - -import {ILegionMetadataStore, LegionGeneration, LegionRarity} from "../interfaces/ILegionMetadataStore.sol"; - -contract LegionMetadataStoreMock is ILegionMetadataStore { - LegionGeneration internal gen; - LegionRarity internal rarity; - - constructor(LegionGeneration _gen, LegionRarity _rarity) { - gen = _gen; - rarity = _rarity; - } - - function genAndRarityForLegion(uint256) external view returns (LegionGeneration gen_, LegionRarity rarity_) { - gen_ = gen; - rarity_ = rarity; - } -} diff --git a/contracts/mock/MagicMock.sol b/contracts/mock/MagicMock.sol deleted file mode 100644 index 6a7ee33..0000000 --- a/contracts/mock/MagicMock.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.28; - -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -contract MagicMock is ERC20("MAGIC Mock", "MAGIC") { - function mint(address _to, uint256 _amount) public { - _mint(_to, _amount); - } -} diff --git a/contracts/mock/MockWeth.sol b/contracts/mock/MockWeth.sol deleted file mode 100644 index 5ba850f..0000000 --- a/contracts/mock/MockWeth.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.28; - -contract MockWeth { - string public name = "Wrapped Ether"; - string public symbol = "WETH"; - uint8 public decimals = 18; - uint256 MAX_INT = 2 ** 256 - 1; - - event Approval(address indexed src, address indexed guy, uint256 wad); - event Transfer(address indexed src, address indexed dst, uint256 wad); - event Deposit(address indexed dst, uint256 wad); - event Withdrawal(address indexed src, uint256 wad); - - mapping(address => uint256) public balanceOf; - mapping(address => mapping(address => uint256)) public allowance; - - fallback() external payable { - deposit(); - } - - function deposit() public payable { - balanceOf[msg.sender] += msg.value; - emit Deposit(msg.sender, msg.value); - } - - function withdraw(uint256 wad) public { - require(balanceOf[msg.sender] >= wad); - balanceOf[msg.sender] -= wad; - (bool success,) = payable(msg.sender).call{value: wad}(""); - require(success, "Transfer failed"); - emit Withdrawal(msg.sender, wad); - } - - function totalSupply() public view returns (uint256) { - return address(this).balance; - } - - function approve(address guy, uint256 wad) public returns (bool) { - allowance[msg.sender][guy] = wad; - emit Approval(msg.sender, guy, wad); - return true; - } - - function transfer(address dst, uint256 wad) public returns (bool) { - return transferFrom(msg.sender, dst, wad); - } - - function transferFrom(address src, address dst, uint256 wad) public returns (bool) { - require(balanceOf[src] >= wad); - - if (src != msg.sender && allowance[src][msg.sender] != MAX_INT) { - require(allowance[src][msg.sender] >= wad); - allowance[src][msg.sender] -= wad; - } - - balanceOf[src] -= wad; - balanceOf[dst] += wad; - - emit Transfer(src, dst, wad); - - return true; - } -} diff --git a/contracts/mock/PlaceholderToken.sol b/contracts/mock/PlaceholderToken.sol deleted file mode 100644 index 555de23..0000000 --- a/contracts/mock/PlaceholderToken.sol +++ /dev/null @@ -1,6 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.28; - -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; - -contract PlaceholderToken is ERC20("Placeholder Token", "PLACEHOLDER") {} diff --git a/contracts/mock/Proxy.sol b/contracts/mock/Proxy.sol deleted file mode 100644 index a4943e5..0000000 --- a/contracts/mock/Proxy.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -// EIP-1967 -abstract contract Proxy { - // /////////////////////// EVENTS /////////////////////////////////////////////////////////////////////////// - - event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation); - - // ///////////////////// EXTERNAL /////////////////////////////////////////////////////////////////////////// - - receive() external payable virtual { - revert("ETHER_REJECTED"); // explicit reject by default - } - - fallback() external payable { - _fallback(); - } - - // ///////////////////////// INTERNAL ////////////////////////////////////////////////////////////////////// - - function _fallback() internal { - // solhint-disable-next-line security/no-inline-assembly - assembly { - let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc) - calldatacopy(0x0, 0x0, calldatasize()) - let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0) - let retSz := returndatasize() - returndatacopy(0, 0, retSz) - switch success - case 0 { revert(0, retSz) } - default { return(0, retSz) } - } - } - - function _setImplementation(address newImplementation, bytes memory data) internal { - address previousImplementation; - // solhint-disable-next-line security/no-inline-assembly - assembly { - previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc) - } - - // solhint-disable-next-line security/no-inline-assembly - assembly { - sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation) - } - - emit ProxyImplementationUpdated(previousImplementation, newImplementation); - - if (data.length > 0) { - (bool success,) = newImplementation.delegatecall(data); - if (!success) { - assembly { - // This assembly ensure the revert contains the exact string data - let returnDataSize := returndatasize() - returndatacopy(0, 0, returnDataSize) - revert(0, returnDataSize) - } - } - } - } -} diff --git a/contracts/mock/openzeppelin/GSN/Context.sol b/contracts/mock/openzeppelin/GSN/Context.sol deleted file mode 100644 index 26e56a0..0000000 --- a/contracts/mock/openzeppelin/GSN/Context.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.0; - -/* - * @dev Provides information about the current execution context, including the - * sender of the transaction and its data. While these are generally available - * via msg.sender and msg.data, they should not be accessed in such a direct - * manner, since when dealing with GSN meta-transactions the account sending and - * paying for execution may not be the actual sender (as far as an application - * is concerned). - * - * This contract is only required for intermediate, library-like contracts. - */ -abstract contract Context { - function _msgSender() internal view virtual returns (address payable) { - return msg.sender; - } - - function _msgData() internal view virtual returns (bytes memory) { - this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 - return msg.data; - } -} diff --git a/contracts/mock/openzeppelin/access/Ownable.sol b/contracts/mock/openzeppelin/access/Ownable.sol deleted file mode 100644 index a67c819..0000000 --- a/contracts/mock/openzeppelin/access/Ownable.sol +++ /dev/null @@ -1,68 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.0; - -import "../GSN/Context.sol"; -/** - * @dev Contract module which provides a basic access control mechanism, where - * there is an account (an owner) that can be granted exclusive access to - * specific functions. - * - * By default, the owner account will be the one that deploys the contract. This - * can later be changed with {transferOwnership}. - * - * This module is used through inheritance. It will make available the modifier - * `onlyOwner`, which can be applied to your functions to restrict their use to - * the owner. - */ - -contract Ownable is Context { - address private _owner; - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - /** - * @dev Initializes the contract setting the deployer as the initial owner. - */ - constructor(address initialOwner) { - _owner = initialOwner; - emit OwnershipTransferred(address(0), initialOwner); - } - - /** - * @dev Returns the address of the current owner. - */ - function owner() public view returns (address) { - return _owner; - } - - /** - * @dev Throws if called by any account other than the owner. - */ - modifier onlyOwner() { - require(_owner == _msgSender(), "Ownable: caller is not the owner"); - _; - } - - /** - * @dev Leaves the contract without owner. It will not be possible to call - * `onlyOwner` functions anymore. Can only be called by the current owner. - * - * NOTE: Renouncing ownership will leave the contract without an owner, - * thereby removing any functionality that is only available to the owner. - */ - function renounceOwnership() public virtual onlyOwner { - emit OwnershipTransferred(_owner, address(0)); - _owner = address(0); - } - - /** - * @dev Transfers ownership of the contract to a new account (`newOwner`). - * Can only be called by the current owner. - */ - function transferOwnership(address newOwner) public virtual onlyOwner { - require(newOwner != address(0), "Ownable: new owner is the zero address"); - emit OwnershipTransferred(_owner, newOwner); - _owner = newOwner; - } -} diff --git a/contracts/mock/openzeppelin/proxy/Proxy.sol b/contracts/mock/openzeppelin/proxy/Proxy.sol deleted file mode 100644 index 0d78a20..0000000 --- a/contracts/mock/openzeppelin/proxy/Proxy.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.0; - -/** - * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM - * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to - * be specified by overriding the virtual {_implementation} function. - * - * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a - * different contract through the {_delegate} function. - * - * The success and return data of the delegated call will be returned back to the caller of the proxy. - */ -abstract contract Proxy { - /** - * @dev Delegates the current call to `implementation`. - * - * This function does not return to its internall call site, it will return directly to the external caller. - */ - function _delegate(address implementation) internal { - // solhint-disable-next-line no-inline-assembly - assembly { - // Copy msg.data. We take full control of memory in this inline assembly - // block because it will not return to Solidity code. We overwrite the - // Solidity scratch pad at memory position 0. - calldatacopy(0, 0, calldatasize()) - - // Call the implementation. - // out and outsize are 0 because we don't know the size yet. - let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) - - // Copy the returned data. - returndatacopy(0, 0, returndatasize()) - - switch result - // delegatecall returns 0 on error. - case 0 { revert(0, returndatasize()) } - default { return(0, returndatasize()) } - } - } - - /** - * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function - * and {_fallback} should delegate. - */ - function _implementation() internal view virtual returns (address); - - /** - * @dev Delegates the current call to the address returned by `_implementation()`. - * - * This function does not return to its internall call site, it will return directly to the external caller. - */ - function _fallback() internal { - _beforeFallback(); - _delegate(_implementation()); - } - - /** - * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other - * function in the contract matches the call data. - */ - fallback() external payable { - _fallback(); - } - - /** - * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data - * is empty. - */ - receive() external payable { - _fallback(); - } - - /** - * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` - * call, or as part of the Solidity `fallback` or `receive` functions. - * - * If overriden should call `super._beforeFallback()`. - */ - function _beforeFallback() internal virtual {} -} diff --git a/contracts/mock/openzeppelin/proxy/ProxyAdmin.sol b/contracts/mock/openzeppelin/proxy/ProxyAdmin.sol deleted file mode 100644 index 8deb2e6..0000000 --- a/contracts/mock/openzeppelin/proxy/ProxyAdmin.sol +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.0; - -import "../access/Ownable.sol"; -import "./TransparentUpgradeableProxy.sol"; - -/** - * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an - * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}. - */ -contract ProxyAdmin is Ownable { - constructor(address owner) Ownable(owner) {} - - /** - * @dev Returns the current implementation of `proxy`. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - */ - function getProxyImplementation(TransparentUpgradeableProxy proxy) public view returns (address) { - // We need to manually run the static call since the getter cannot be flagged as view - // bytes4(keccak256("implementation()")) == 0x5c60da1b - (bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b"); - require(success); - return abi.decode(returndata, (address)); - } - - /** - * @dev Returns the current admin of `proxy`. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - */ - function getProxyAdmin(TransparentUpgradeableProxy proxy) public view returns (address) { - // We need to manually run the static call since the getter cannot be flagged as view - // bytes4(keccak256("admin()")) == 0xf851a440 - (bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440"); - require(success); - return abi.decode(returndata, (address)); - } - - /** - * @dev Changes the admin of `proxy` to `newAdmin`. - * - * Requirements: - * - * - This contract must be the current admin of `proxy`. - */ - function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public onlyOwner { - proxy.changeAdmin(newAdmin); - } - - /** - * @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - */ - function upgrade(TransparentUpgradeableProxy proxy, address implementation) public onlyOwner { - proxy.upgradeTo(implementation); - } - - /** - * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See - * {TransparentUpgradeableProxy-upgradeToAndCall}. - * - * Requirements: - * - * - This contract must be the admin of `proxy`. - */ - function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) - public - payable - onlyOwner - { - proxy.upgradeToAndCall{value: msg.value}(implementation, data); - } -} diff --git a/contracts/mock/openzeppelin/proxy/TransparentUpgradeableProxy.sol b/contracts/mock/openzeppelin/proxy/TransparentUpgradeableProxy.sol deleted file mode 100644 index 90ddcea..0000000 --- a/contracts/mock/openzeppelin/proxy/TransparentUpgradeableProxy.sol +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.0; - -import "./UpgradeableProxy.sol"; - -/** - * @dev This contract implements a proxy that is upgradeable by an admin. - * - * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector - * clashing], which can potentially be used in an attack, this contract uses the - * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two - * things that go hand in hand: - * - * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if - * that call matches one of the admin functions exposed by the proxy itself. - * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the - * implementation. If the admin tries to call a function on the implementation it will fail with an error that says - * "admin cannot fallback to proxy target". - * - * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing - * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due - * to sudden errors when trying to call a function from the proxy implementation. - * - * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, - * you should think of the `ProxyAdmin` instance as the real administrative inerface of your proxy. - */ -contract TransparentUpgradeableProxy is UpgradeableProxy { - /** - * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and - * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}. - */ - constructor(address initialLogic, address initialAdmin, bytes memory _data) - payable - UpgradeableProxy(initialLogic, _data) - { - assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)); - _setAdmin(initialAdmin); - } - - /** - * @dev Emitted when the admin account has changed. - */ - event AdminChanged(address previousAdmin, address newAdmin); - - /** - * @dev Storage slot with the admin of the contract. - * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - - /** - * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. - */ - modifier ifAdmin() { - if (msg.sender == _admin()) { - _; - } else { - _fallback(); - } - } - - /** - * @dev Returns the current admin. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. - * - * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the - * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. - * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` - */ - function admin() external ifAdmin returns (address) { - return _admin(); - } - - /** - * @dev Returns the current implementation. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. - * - * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the - * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. - * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` - */ - function implementation() external ifAdmin returns (address) { - return _implementation(); - } - - /** - * @dev Changes the admin of the proxy. - * - * Emits an {AdminChanged} event. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}. - */ - function changeAdmin(address newAdmin) external ifAdmin { - require(newAdmin != address(0), "TransparentUpgradeableProxy: new admin is the zero address"); - emit AdminChanged(_admin(), newAdmin); - _setAdmin(newAdmin); - } - - /** - * @dev Upgrade the implementation of the proxy. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. - */ - function upgradeTo(address newImplementation) external ifAdmin { - _upgradeTo(newImplementation); - } - - /** - * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified - * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the - * proxied contract. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. - */ - function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { - _upgradeTo(newImplementation); - // solhint-disable-next-line avoid-low-level-calls - (bool success,) = newImplementation.delegatecall(data); - require(success); - } - - /** - * @dev Returns the current admin. - */ - function _admin() internal view returns (address) { - bytes32 slot = _ADMIN_SLOT; - address adm; - // solhint-disable-next-line no-inline-assembly - assembly { - adm := sload(slot) - } - return adm; - } - - /** - * @dev Stores a new address in the EIP1967 admin slot. - */ - function _setAdmin(address newAdmin) private { - bytes32 slot = _ADMIN_SLOT; - - // solhint-disable-next-line no-inline-assembly - assembly { - sstore(slot, newAdmin) - } - } - - /** - * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. - */ - function _beforeFallback() internal virtual override { - require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target"); - super._beforeFallback(); - } -} diff --git a/contracts/mock/openzeppelin/proxy/UpgradeableProxy.sol b/contracts/mock/openzeppelin/proxy/UpgradeableProxy.sol deleted file mode 100644 index 53200d7..0000000 --- a/contracts/mock/openzeppelin/proxy/UpgradeableProxy.sol +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.0; - -import "./Proxy.sol"; -import "../utils/Address.sol"; - -/** - * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an - * implementation address that can be changed. This address is stored in storage in the location specified by - * https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the - * implementation behind the proxy. - * - * Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see - * {TransparentUpgradeableProxy}. - */ -contract UpgradeableProxy is Proxy { - /** - * @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`. - * - * If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded - * function call, and allows initializating the storage of the proxy like a Solidity constructor. - */ - constructor(address _logic, bytes memory _data) payable { - assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1)); - _setImplementation(_logic); - if (_data.length > 0) { - // solhint-disable-next-line avoid-low-level-calls - (bool success,) = _logic.delegatecall(_data); - require(success); - } - } - - /** - * @dev Emitted when the implementation is upgraded. - */ - event Upgraded(address indexed implementation); - - /** - * @dev Storage slot with the address of the current implementation. - * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; - - /** - * @dev Returns the current implementation address. - */ - function _implementation() internal view override returns (address impl) { - bytes32 slot = _IMPLEMENTATION_SLOT; - // solhint-disable-next-line no-inline-assembly - assembly { - impl := sload(slot) - } - } - - /** - * @dev Upgrades the proxy to a new implementation. - * - * Emits an {Upgraded} event. - */ - function _upgradeTo(address newImplementation) internal { - _setImplementation(newImplementation); - emit Upgraded(newImplementation); - } - - /** - * @dev Stores a new address in the EIP1967 implementation slot. - */ - function _setImplementation(address newImplementation) private { - require(Address.isContract(newImplementation), "UpgradeableProxy: new implementation is not a contract"); - - bytes32 slot = _IMPLEMENTATION_SLOT; - - // solhint-disable-next-line no-inline-assembly - assembly { - sstore(slot, newImplementation) - } - } -} diff --git a/contracts/mock/openzeppelin/utils/Address.sol b/contracts/mock/openzeppelin/utils/Address.sol deleted file mode 100644 index 53e6a2a..0000000 --- a/contracts/mock/openzeppelin/utils/Address.sol +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.0; - -/** - * @dev Collection of functions related to the address type - */ -library Address { - /** - * @dev Returns true if `account` is a contract. - * - * [IMPORTANT] - * ==== - * It is unsafe to assume that an address for which this function returns - * false is an externally-owned account (EOA) and not a contract. - * - * Among others, `isContract` will return false for the following - * types of addresses: - * - * - an externally-owned account - * - a contract in construction - * - an address where a contract will be created - * - an address where a contract lived, but was destroyed - * ==== - */ - 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); - } - - /** - * @dev Replacement for Solidity's `transfer`: sends `amount` wei to - * `recipient`, forwarding all available gas and reverting on errors. - * - * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost - * of certain opcodes, possibly making contracts go over the 2300 gas limit - * imposed by `transfer`, making them unable to receive funds via - * `transfer`. {sendValue} removes this limitation. - * - * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. - * - * IMPORTANT: because control is transferred to `recipient`, care must be - * taken to not create reentrancy vulnerabilities. Consider using - * {ReentrancyGuard} or the - * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. - */ - function sendValue(address payable recipient, uint256 amount) internal { - require(address(this).balance >= amount, "Address: insufficient balance"); - - // solhint-disable-next-line avoid-low-level-calls, avoid-call-value - (bool success,) = recipient.call{value: amount}(""); - require(success, "Address: unable to send value, recipient may have reverted"); - } - - /** - * @dev Performs a Solidity function call using a low level `call`. A - * plain`call` is an unsafe replacement for a function call: use this - * function instead. - * - * If `target` reverts with a revert reason, it is bubbled up by this - * function (like regular Solidity function calls). - * - * Returns the raw returned data. To convert to the expected return value, - * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. - * - * Requirements: - * - * - `target` must be a contract. - * - calling `target` with `data` must not revert. - * - * _Available since v3.1._ - */ - function functionCall(address target, bytes memory data) internal returns (bytes memory) { - return functionCall(target, data, "Address: low-level call failed"); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with - * `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCall(address target, bytes memory data, string memory errorMessage) - internal - returns (bytes memory) - { - return _functionCallWithValue(target, data, 0, errorMessage); - } - - /** - * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], - * but also transferring `value` wei to `target`. - * - * Requirements: - * - * - the calling contract must have an ETH balance of at least `value`. - * - the called Solidity function must be `payable`. - * - * _Available since v3.1._ - */ - function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { - return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); - } - - /** - * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but - * with `errorMessage` as a fallback revert reason when `target` reverts. - * - * _Available since v3.1._ - */ - function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) - internal - returns (bytes memory) - { - require(address(this).balance >= value, "Address: insufficient balance for call"); - return _functionCallWithValue(target, data, value, errorMessage); - } - - function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) - private - returns (bytes memory) - { - require(isContract(target), "Address: call to non-contract"); - - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory returndata) = target.call{value: weiValue}(data); - if (success) { - return returndata; - } else { - // Look for revert reason and bubble it up if present - if (returndata.length > 0) { - // The easiest way to bubble the revert reason is using memory via assembly - - // solhint-disable-next-line no-inline-assembly - assembly { - let returndata_size := mload(returndata) - revert(add(32, returndata), returndata_size) - } - } else { - revert(errorMessage); - } - } - } -} diff --git a/contracts/mock/proxy/EIP173Proxy.sol b/contracts/mock/proxy/EIP173Proxy.sol deleted file mode 100644 index 441ba86..0000000 --- a/contracts/mock/proxy/EIP173Proxy.sol +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import "./Proxy.sol"; - -interface ERC165 { - function supportsInterface(bytes4 id) external view returns (bool); -} - -///@notice Proxy implementing EIP173 for ownership management -contract EIP173Proxy is Proxy { - // ////////////////////////// EVENTS /////////////////////////////////////////////////////////////////////// - - event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); - - // /////////////////////// CONSTRUCTOR ////////////////////////////////////////////////////////////////////// - - constructor(address implementationAddress, address ownerAddress, bytes memory data) payable { - _setImplementation(implementationAddress, data); - _setOwner(ownerAddress); - } - - // ///////////////////// EXTERNAL /////////////////////////////////////////////////////////////////////////// - - function owner() external view returns (address) { - return _owner(); - } - - function supportsInterface(bytes4 id) external view returns (bool) { - if (id == 0x01ffc9a7 || id == 0x7f5828d0) { - return true; - } - if (id == 0xFFFFFFFF) { - return false; - } - - ERC165 implementation; - // solhint-disable-next-line security/no-inline-assembly - assembly { - implementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc) - } - - // Technically this is not standard compliant as ERC-165 require 30,000 gas which that call cannot ensure - // because it is itself inside `supportsInterface` that might only get 30,000 gas. - // In practise this is unlikely to be an issue. - try implementation.supportsInterface(id) returns (bool support) { - return support; - } catch { - return false; - } - } - - function transferOwnership(address newOwner) external onlyOwner { - _setOwner(newOwner); - } - - function upgradeTo(address newImplementation) external onlyOwner { - _setImplementation(newImplementation, ""); - } - - function upgradeToAndCall(address newImplementation, bytes calldata data) external payable onlyOwner { - _setImplementation(newImplementation, data); - } - - // /////////////////////// MODIFIERS //////////////////////////////////////////////////////////////////////// - - modifier onlyOwner() { - require(msg.sender == _owner(), "NOT_AUTHORIZED"); - _; - } - - // ///////////////////////// INTERNAL ////////////////////////////////////////////////////////////////////// - - function _owner() internal view returns (address adminAddress) { - // solhint-disable-next-line security/no-inline-assembly - assembly { - adminAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103) - } - } - - function _setOwner(address newOwner) internal { - address previousOwner = _owner(); - // solhint-disable-next-line security/no-inline-assembly - assembly { - sstore(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, newOwner) - } - emit OwnershipTransferred(previousOwner, newOwner); - } -} diff --git a/contracts/mock/proxy/EIP173ProxyWithReceive.sol b/contracts/mock/proxy/EIP173ProxyWithReceive.sol deleted file mode 100644 index 334e7df..0000000 --- a/contracts/mock/proxy/EIP173ProxyWithReceive.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import "./EIP173Proxy.sol"; - -///@notice Proxy implementing EIP173 for ownership management that accept ETH via receive -contract EIP173ProxyWithReceive is EIP173Proxy { - constructor(address implementationAddress, address ownerAddress, bytes memory data) - payable - EIP173Proxy(implementationAddress, ownerAddress, data) - {} - - receive() external payable override {} -} diff --git a/contracts/mock/proxy/OptimizedTransparentUpgradeableProxy.sol b/contracts/mock/proxy/OptimizedTransparentUpgradeableProxy.sol deleted file mode 100644 index 3421a57..0000000 --- a/contracts/mock/proxy/OptimizedTransparentUpgradeableProxy.sol +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -import "../openzeppelin/proxy/UpgradeableProxy.sol"; - -/** - * @dev This contract implements a proxy that is upgradeable by an admin. - * - * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector - * clashing], which can potentially be used in an attack, this contract uses the - * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two - * things that go hand in hand: - * - * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if - * that call matches one of the admin functions exposed by the proxy itself. - * 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the - * implementation. If the admin tries to call a function on the implementation it will fail with an error that says - * "admin cannot fallback to proxy target". - * - * These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing - * the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due - * to sudden errors when trying to call a function from the proxy implementation. - * - * Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way, - * you should think of the `ProxyAdmin` instance as the real administrative inerface of your proxy. - */ -contract OptimizedTransparentUpgradeableProxy is UpgradeableProxy { - address internal immutable _ADMIN; - - /** - * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and - * optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}. - */ - constructor(address initialLogic, address initialAdmin, bytes memory _data) - payable - UpgradeableProxy(initialLogic, _data) - { - assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1)); - bytes32 slot = _ADMIN_SLOT; - - _ADMIN = initialAdmin; - - // still store it to work with EIP-1967 - // solhint-disable-next-line no-inline-assembly - assembly { - sstore(slot, initialAdmin) - } - } - - /** - * @dev Storage slot with the admin of the contract. - * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is - * validated in the constructor. - */ - bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; - - /** - * @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin. - */ - modifier ifAdmin() { - if (msg.sender == _admin()) { - _; - } else { - _fallback(); - } - } - - /** - * @dev Returns the current admin. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}. - * - * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the - * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. - * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103` - */ - function admin() external ifAdmin returns (address) { - return _admin(); - } - - /** - * @dev Returns the current implementation. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}. - * - * TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the - * https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call. - * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc` - */ - function implementation() external ifAdmin returns (address) { - return _implementation(); - } - - /** - * @dev Upgrade the implementation of the proxy. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}. - */ - function upgradeTo(address newImplementation) external ifAdmin { - _upgradeTo(newImplementation); - } - - /** - * @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified - * by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the - * proxied contract. - * - * NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}. - */ - function upgradeToAndCall(address newImplementation, bytes calldata data) external payable ifAdmin { - _upgradeTo(newImplementation); - // solhint-disable-next-line avoid-low-level-calls - (bool success,) = newImplementation.delegatecall(data); - require(success); - } - - /** - * @dev Returns the current admin. - */ - function _admin() internal view returns (address) { - return _ADMIN; - } - - /** - * @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}. - */ - function _beforeFallback() internal virtual override { - require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target"); - super._beforeFallback(); - } -} diff --git a/contracts/mock/proxy/Proxied.sol b/contracts/mock/proxy/Proxied.sol deleted file mode 100644 index d1d4a0b..0000000 --- a/contracts/mock/proxy/Proxied.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -abstract contract Proxied { - /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them - /// It also allows these functions to be called inside a contructor - /// even if the contract is meant to be used without proxy - modifier proxied() { - address proxyAdminAddress = _proxyAdmin(); - // With hardhat-deploy proxies - // the proxyAdminAddress is zero only for the implementation contract - // if the implementation contract want to be used as a standalone/immutable contract - // it simply has to execute the `proxied` function - // This ensure the proxyAdminAddress is never zero post deployment - // And allow you to keep the same code for both proxied contract and immutable contract - if (proxyAdminAddress == address(0)) { - // ensure can not be called twice when used outside of proxy : no admin - // solhint-disable-next-line security/no-inline-assembly - assembly { - sstore( - 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ) - } - } else { - require(msg.sender == proxyAdminAddress); - } - _; - } - - modifier onlyProxyAdmin() { - require(msg.sender == _proxyAdmin(), "NOT_AUTHORIZED"); - _; - } - - function _proxyAdmin() internal view returns (address ownerAddress) { - // solhint-disable-next-line security/no-inline-assembly - assembly { - ownerAddress := sload(0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103) - } - } -} diff --git a/contracts/mock/proxy/Proxy.sol b/contracts/mock/proxy/Proxy.sol deleted file mode 100644 index a4943e5..0000000 --- a/contracts/mock/proxy/Proxy.sol +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -// EIP-1967 -abstract contract Proxy { - // /////////////////////// EVENTS /////////////////////////////////////////////////////////////////////////// - - event ProxyImplementationUpdated(address indexed previousImplementation, address indexed newImplementation); - - // ///////////////////// EXTERNAL /////////////////////////////////////////////////////////////////////////// - - receive() external payable virtual { - revert("ETHER_REJECTED"); // explicit reject by default - } - - fallback() external payable { - _fallback(); - } - - // ///////////////////////// INTERNAL ////////////////////////////////////////////////////////////////////// - - function _fallback() internal { - // solhint-disable-next-line security/no-inline-assembly - assembly { - let implementationAddress := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc) - calldatacopy(0x0, 0x0, calldatasize()) - let success := delegatecall(gas(), implementationAddress, 0x0, calldatasize(), 0, 0) - let retSz := returndatasize() - returndatacopy(0, 0, retSz) - switch success - case 0 { revert(0, retSz) } - default { return(0, retSz) } - } - } - - function _setImplementation(address newImplementation, bytes memory data) internal { - address previousImplementation; - // solhint-disable-next-line security/no-inline-assembly - assembly { - previousImplementation := sload(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc) - } - - // solhint-disable-next-line security/no-inline-assembly - assembly { - sstore(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc, newImplementation) - } - - emit ProxyImplementationUpdated(previousImplementation, newImplementation); - - if (data.length > 0) { - (bool success,) = newImplementation.delegatecall(data); - if (!success) { - assembly { - // This assembly ensure the revert contains the exact string data - let returnDataSize := returndatasize() - returndatacopy(0, 0, returnDataSize) - revert(0, returnDataSize) - } - } - } - } -}