Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- xSHRAPKava
- Optimization enabled
- true
- Compiler version
- v0.8.19+commit.7dd6d404
- Optimization runs
- 10000
- Verified at
- 2023-03-21T18:15:44.610313Z
/contracts/xShrap-kava.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Implementation of LZ 1822/1967 ERC20 * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./Max-20-Burnable-UUPS-LZ.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; contract xSHRAPKava is Initializable , Max20BurnUUPSLZ , UUPSUpgradeable { using Lib20 for Lib20.Token; using Safe20 for IERC20; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( address _admin , address _mint ) initializer public { __Max20_init("xSHRAP", "xSHRAP", 18, _admin); __UUPSUpgradeable_init(); token20.mint(_mint, 500 ether); emit Transfer(address(0), _mint, 500 ether); } function _authorizeUpgrade(address newImplementation) internal onlyRole(ADMIN) override {} // @notice: This function transfers the ft from your address on the // source chain to the same address on the destination chain // @param _chainId: the uint16 of desination chain (see LZ docs) // @param _amount: amount to be sent function traverseChains( uint16 _chainId , uint256 _amount ) public virtual payable { uint256 userBal = token20.getBalanceOf(msg.sender); if (_amount > userBal) { revert Unauthorized(); } if (trustedRemoteLookup[_chainId].length == 0) { revert MaxSplaining({ reason: "Token: TR not set" }); } // burn , eliminating it from circulation on src chain token20.burn(msg.sender, _amount); emit Transfer(msg.sender, address(0), _amount); // abi.encode() the payload with the values to send bytes memory payload = abi.encode( msg.sender , _amount); // encode adapterParams to specify more gas for the destination uint16 version = 1; bytes memory adapterParams = abi.encodePacked( version , gasForDestinationLzReceive); // get the fees we need to pay to LayerZero + Relayer to cover message delivery // you will be refunded for extra gas paid (uint messageFee, ) = endpoint.estimateFees( _chainId , address(this) , payload , false , adapterParams); // revert this transaction if the fees are not met if (messageFee > msg.value) { revert MaxSplaining({ reason: "Token: message fee low" }); } // send the transaction to the endpoint endpoint.send{value: msg.value}( _chainId, // destination chainId trustedRemoteLookup[_chainId], // destination address of nft contract payload, // abi.encoded()'ed bytes payable(msg.sender), // refund address address(0x0), // 'zroPaymentAddress' unused for this adapterParams // txParameters ); } // @notice: just in case this fixed variable limits us from future integrations // @param newVal: new value for gas amount function setGasForDestinationLzReceive( uint newVal ) external onlyDev() { gasForDestinationLzReceive = newVal; } // @notice internal function to mint FT from migration // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) override internal { // decode (address toAddr, uint256 amount) = abi.decode(_payload, (address, uint256)); // mint the tokens back into existence on destination chain token20.mint(toAddr, amount); emit Transfer(address(0), toAddr, amount); } // @notice: will return gas value for LZ // @return: uint for gas value function currentLZGas() external view returns (uint256) { return gasForDestinationLzReceive; } }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
/contracts/Max-20-Burnable-UUPS-LZ.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title Max-20-Burnable-UUPS-LZ * @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @custom:change-log updates L241 TransferFrom to include redux in Approval */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; import "./eip/20/IERC20.sol"; import "./eip/20/IERC20Burnable.sol"; import "./lib/Safe20.sol"; import "./lib/20.sol"; import "./modules/access/MaxAccess.sol"; import "./lib/Roles.sol"; import "./lz/ILayerZeroReceiver.sol"; import "./lz/ILayerZeroEndpoint.sol"; import "./errors/MaxErrors.sol"; abstract contract Max20BurnUUPSLZ is Initializable , MaxErrors , MaxAccess , ILayerZeroReceiver , IERC20Burnable , IERC20 { ////////////////////////////////////// // Storage ////////////////////////////////////// using Lib20 for Lib20.Token; using Roles for Roles.Role; using Safe20 for IERC20; Lib20.Token internal token20; Roles.Role internal contractRoles; address internal Token; bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal PENDING_DEVS = 0xca4b208a; // DEVS - 1 bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal PENDING_OWNERS = 0x8da5cb5a; // OWNERS - 1 bytes4 constant internal ADMIN = 0xf851a440; ////////////////////////////////////// // LayerZero Storage ////////////////////////////////////// ILayerZeroEndpoint internal endpoint; struct FailedMessages { uint payloadLength; bytes32 payloadHash; } mapping(uint16 => mapping(bytes => mapping(uint => FailedMessages))) public failedMessages; mapping(uint16 => bytes) public trustedRemoteLookup; uint256 internal gasForDestinationLzReceive; event TrustedRemoteSet(uint16 _chainId, bytes _trustedRemote); event EndpointSet(address indexed _endpoint); event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload); /////////////////////// // MAX-20: Modifiers /////////////////////// modifier onlyRole(bytes4 role) { if (contractRoles.has(role, msg.sender) || contractRoles.has(ADMIN, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyOwner() { if (contractRoles.has(OWNERS, msg.sender)) { _; } else { revert Unauthorized(); } } modifier onlyDev() { if (contractRoles.has(DEVS, msg.sender)) { _; } else { revert Unauthorized(); } } /////////////////////// /// MAX-20: Internals /////////////////////// function __Max20_init( string memory _name , string memory _symbol , uint8 _decimals , address _admin ) internal onlyInitializing() { token20.setName(_name); token20.setSymbol(_symbol); token20.setDecimals(_decimals); contractRoles.add(ADMIN, _admin); contractRoles.setAdmin(_admin); contractRoles.add(DEVS, _admin); contractRoles.setDeveloper(_admin); contractRoles.add(OWNERS, _admin); contractRoles.setOwner(_admin); } ////////////////////////// // EIP-20: Token Standard ////////////////////////// /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view virtual override returns (string memory) { return token20.getName(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view virtual override returns (string memory) { return token20.getSymbol(); } /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view virtual override returns (uint8) { return token20.getDecimals(); } /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view virtual override returns (uint256) { return token20.getTotalSupply(); } /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view virtual override returns (uint256 balance) { balance = token20.getBalanceOf(_owner); } /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_to == address(0)) { revert MaxSplaining({ reason: "Max20: to address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { success = token20.doTransfer(msg.sender, _to, _value); emit Transfer(msg.sender, _to, _value); } } /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0) || _to == address(0)) { revert MaxSplaining({ reason: "Max20: to/from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { success = token20.doTransfer(_from, _to, _value); emit Transfer(_from, _to, _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external virtual override returns (bool success) { success = token20.setApprove(msg.sender, _spender, _value); emit Approval(msg.sender, _spender, _value); } /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view virtual override returns (uint256 remaining) { remaining = token20.getAllowance(_owner, _spender); } /////////////////// /// EIP-20: Burnable /////////////////// /// @dev to burn ERC20 tokens /// @param _value uint256 amount of tokens to burn function burn( uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(msg.sender); if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else { token20.burn(msg.sender, _value); success = true; emit Transfer(msg.sender, address(0), _value); } } /// @dev to burn ERC20 tokens from someone /// @param _from address to burn from /// @param _value uint256 amount of tokens to burn function burnFrom( address _from , uint256 _value ) external virtual override returns (bool success) { uint256 balanceUser = this.balanceOf(_from); uint256 approveBal = this.allowance(_from, msg.sender); if (_from == address(0)) { revert MaxSplaining({ reason: "Max20: from address(0)" }); } else if (_value > balanceUser) { revert MaxSplaining({ reason: "Max20: issuficient balance" }); } else if (_value > approveBal) { revert MaxSplaining({ reason: "Max20: not approved to spend _value" }); } else { token20.burn(_from, _value); success = true; emit Transfer(_from, address(0), _value); token20.setApprove(_from, msg.sender, approveBal - _value); emit Approval(_from, msg.sender, approveBal - _value); } } /////////////////// /// LayerZero: NBR /////////////////// // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) external override { if (msg.sender != address(endpoint)) { revert MaxSplaining({ reason: "NBR:1" }); } if ( _srcAddress.length != trustedRemoteLookup[_srcChainId].length || keccak256(_srcAddress) != keccak256(trustedRemoteLookup[_srcChainId]) ) { revert MaxSplaining({ reason: "NBR:2" }); } // try-catch all errors/exceptions // having failed messages does not block messages passing try this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload) { // do nothing } catch { // error or exception failedMessages[_srcChainId][_srcAddress][_nonce] = FailedMessages(_payload.length, keccak256(_payload)); emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload); } } // @notice this is the catch all above (should be an internal?) // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function onLzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) public { // only internal transaction if (msg.sender != address(this)) { revert MaxSplaining({ reason: "NBR:3" }); } // handle incoming message _LzReceive( _srcChainId, _srcAddress, _nonce, _payload); } // @notice internal function to do something in the main contract // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function _LzReceive( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes memory _payload ) virtual internal; // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function _lzSend( uint16 _dstChainId , bytes memory _payload , address payable _refundAddress , address _zroPaymentAddress , bytes memory _txParam ) internal { endpoint.send{value: msg.value}( _dstChainId , trustedRemoteLookup[_dstChainId] , _payload, _refundAddress , _zroPaymentAddress , _txParam); } // @notice this is to retry a failed message on LayerZero // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _nonce - the ordered message nonce // @param _payload - the payload to be retried function retryMessage( uint16 _srcChainId , bytes memory _srcAddress , uint64 _nonce , bytes calldata _payload ) external payable { // assert there is message to retry FailedMessages storage failedMsg = failedMessages[_srcChainId][_srcAddress][_nonce]; if (failedMsg.payloadHash == bytes32(0)) { revert MaxSplaining({ reason: "NBR:4" }); } if ( _payload.length != failedMsg.payloadLength || keccak256(_payload) != failedMsg.payloadHash ) { revert MaxSplaining({ reason: "NBR:5" }); } // clear the stored message failedMsg.payloadLength = 0; failedMsg.payloadHash = bytes32(0); // execute the message. revert if it fails again this.onLzReceive(_srcChainId, _srcAddress, _nonce, _payload); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setTrustedRemote( uint16 _chainId , bytes calldata _trustedRemote ) external onlyDev() { trustedRemoteLookup[_chainId] = _trustedRemote; emit TrustedRemoteSet(_chainId, _trustedRemote); } // @notice this is to set all valid incoming messages // @param _srcChainId - the source chain identifier // @param _trustedRemote - the source chain contract address function setEndPoint( address newEndpoint ) external onlyDev() { endpoint = ILayerZeroEndpoint(newEndpoint); emit EndpointSet(newEndpoint); } ///////////////////////////////////////// /// EIP-173: Contract Ownership Standard ///////////////////////////////////////// /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address) { return contractRoles.getOwner(); } /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external onlyRole(OWNERS) { contractRoles.add(OWNERS, _newOwner); contractRoles.setOwner(_newOwner); contractRoles.remove(OWNERS, msg.sender); } //////////////////////////////////////////////////////////////// /// EIP-173: Contract Ownership Standard, MaxFlowO2's extension //////////////////////////////////////////////////////////////// /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external onlyRole(OWNERS) { contractRoles.setOwner(address(0)); contractRoles.remove(OWNERS, msg.sender); } /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.add(OWNERS, msg.sender); contractRoles.setOwner(msg.sender); contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external onlyRole(PENDING_OWNERS) { contractRoles.remove(PENDING_OWNERS, msg.sender); } /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external onlyRole(OWNERS) { contractRoles.add(PENDING_OWNERS, newOwner); } ////////////////////////////////////////////// /// [Not an EIP]: Contract Developer Standard ////////////////////////////////////////////// /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address) { return contractRoles.getDeveloper(); } /// @dev This renounces your role as onlyDev() function renounceDeveloper() external onlyRole(DEVS) { contractRoles.setDeveloper(address(0)); contractRoles.remove(DEVS, msg.sender); } /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(DEVS, newDeveloper); contractRoles.setDeveloper(newDeveloper); contractRoles.remove(DEVS, msg.sender); } /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.add(DEVS, msg.sender); contractRoles.setDeveloper(msg.sender); contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external onlyRole(PENDING_DEVS) { contractRoles.remove(PENDING_DEVS, msg.sender); } /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external onlyRole(DEVS) { contractRoles.add(PENDING_DEVS, newDeveloper); } ////////////////////////////////////////// /// [Not an EIP]: Contract Roles Standard ////////////////////////////////////////// /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool) { return contractRoles.has(role, account); } /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4) { return ADMIN; } /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { revert Unauthorized(); } else { contractRoles.add(role, account); } } /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external onlyRole(role) { if (role == PENDING_DEVS || role == PENDING_OWNERS) { if (account == msg.sender) { contractRoles.remove(role, account); } else { revert Unauthorized(); } } else { contractRoles.remove(role, account); } } /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external onlyRole(role) { contractRoles.remove(role, msg.sender); } ////////////////////////////////////////// /// EIP-165: Standard Interface Detection ////////////////////////////////////////// /// @dev Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view virtual override returns (bool) { return ( interfaceID == type(IERC173).interfaceId || interfaceID == type(IMAX173).interfaceId || interfaceID == type(IMAXDEV).interfaceId || interfaceID == type(IRoles).interfaceId || interfaceID == type(IERC20Burnable).interfaceId || interfaceID == type(IERC20).interfaceId ); } uint256[35] private __gap; }
/contracts/eip/165/IERC165.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-165: Standard Interface Detection * @author: Christian Reitwießner, Nick Johnson, Fabian Vogelsteller, Jordi Baylina, Konrad Feldmeier, William Entriken * @dev Creates a standard method to publish and detect what interfaces a smart contract implements. * @custom:source https://eips.ethereum.org/EIPS/eip-165 * @custom:change-log interface ERC165 -> interface IERC165 * @custom:change-log readability enhanced * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface IERC165 { /// @notice Query if a contract implements an interface /// @param interfaceID The interface identifier, as specified in ERC-165 /// @notice Interface identification is specified in ERC-165. This function /// uses less than 30,000 gas. /// @return `true` if the contract implements `interfaceID` and /// `interfaceID` is not 0xffffffff, `false` otherwise function supportsInterface( bytes4 interfaceID ) external view returns (bool); }
/contracts/eip/173/IERC173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard * @author: Nick Mudge, Dan Finlay * @notice: This specification defines standard functions for owning or controlling a contract. * the ERC-165 identifier for this interface is 0x7f5828d0 * @custom:URI https://eips.ethereum.org/EIPS/eip-173 * @custom:change-log MIT -> Apache-2.0 * @custom:change-log readability modification */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IERC173 is IERC165 { /// @dev This emits when ownership of a contract changes. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /// @notice Get the address of the owner /// @return The address of the owner. function owner() view external returns(address); /// @notice Set the address of the new owner of the contract /// @dev Set _newOwner to address(0) to renounce any ownership. /// @param _newOwner The address of the new owner of the contract function transferOwnership( address _newOwner ) external; }
/contracts/eip/20/IERC20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Token Standard * @author: Fabian Vogelsteller, Vitalik Buterin * @dev The following standard allows for the implementation of a standard API for tokens within * smart contracts. This standard provides basic functionality to transfer tokens, as well * as allow tokens to be approved so they can be spent by another on-chain third party. * @custom:source https://eips.ethereum.org/EIPS/eip-20 * @custom:change-log external -> external, string -> string memory (0.8.x) * @custom:change-log readability enhanced * @custom:change-log backwards compatability to EIP 165 added * @custom:change-log MIT -> Apache-2.0 // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20 is IERC165 { /// @dev Transfer Event /// @notice MUST trigger when tokens are transferred, including zero value transfers. /// @notice A token contract which creates new tokens SHOULD trigger a Transfer event /// with the _from address set to 0x0 when tokens are created. event Transfer(address indexed _from, address indexed _to, uint256 _value); /// @dev Approval Event /// @notice MUST trigger on any successful call to approve(address _spender, uint256 _value). event Approval(address indexed _owner, address indexed _spender, uint256 _value); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the name of the token - e.g. "MyToken". function name() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return string memory returns the symbol of the token. E.g. “HIX”. function symbol() external view returns (string memory); /// @dev OPTIONAL - This method can be used to improve usability, but interfaces and other /// contracts MUST NOT expect these values to be present. /// @return uint8 returns the number of decimals the token uses - e.g. 8, means to divide the /// token amount by 100000000 to get its user representation. function decimals() external view returns (uint8); /// @dev totalSupply /// @return uint256 returns the total token supply. function totalSupply() external view returns (uint256); /// @dev balanceOf /// @return balance returns the account balance of another account with address _owner. function balanceOf( address _owner ) external view returns (uint256 balance); /// @dev transfer /// @return success /// @notice Transfers _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to spend. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transfer( address _to , uint256 _value ) external returns (bool success); /// @dev transferFrom /// @return success /// @notice The transferFrom method is used for a withdraw workflow, allowing contracts to transfer /// tokens on your behalf. This can be used for example to allow a contract to transfer /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note Transfers of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function transferFrom( address _from , address _to , uint256 _value ) external returns (bool success); /// @dev approve /// @return success /// @notice Allows _spender to withdraw from your account multiple times, up to the _value amount. /// If this function is called again it overwrites the current allowance with _value. /// @notice To prevent attack vectors like the one described here and discussed here, clients /// SHOULD make sure to create user interfaces in such a way that they set the allowance /// first to 0 before setting it to another value for the same spender. THOUGH The contract /// itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed /// before function approve( address _spender , uint256 _value ) external returns (bool success); /// @dev allowance /// @return remaining uint256 of allowance remaining /// @notice Returns the amount which _spender is still allowed to withdraw from _owner. function allowance( address _owner , address _spender ) external view returns (uint256 remaining); }
/contracts/eip/20/IERC20Burnable.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-20: Extension * @author: Unknown * @notice */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright and related rights waived via CC0. * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../165/IERC165.sol"; interface IERC20Burnable is IERC165 { /// @dev burn /// @return success /// @notice Burns _value amount of tokens to address _to, and MUST fire the Transfer event. /// The function SHOULD throw if the message caller’s account balance does not have enough /// tokens to burn. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burn( uint256 _value ) external returns (bool success); /// @dev burnFrom /// @return success /// @notice The burnFrom method is used for a burn workflow, allowing contracts to burn /// tokens on your behalf. This can be used for example to allow a contract to burn /// tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD /// throw unless the _from account has deliberately authorized the sender of the message /// via some mechanism. /// @notice Note burn of 0 values MUST be treated as normal transfers and fire the Transfer /// event. function burnFrom( address _from , uint256 _value ) external returns (bool success); }
/contracts/errors/MaxErrors.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxErrors, so I can import errors, anywhere minus libraries * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Does not have an ERC165 return since no external/public functions * @custom:change-log abstract contract -> interface */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; interface MaxErrors { /// @dev this is Unauthorized(), basically a catch all, zero description /// @notice 0x82b42900 bytes4 of this error Unauthorized(); /// @dev this is MaxSplaining(), giving you a reason, aka require(param, "reason") /// @param reason: Use the "Contract name: error" /// @notice 0x0661b792 bytes4 of this error MaxSplaining( string reason ); /// @dev this is TooSoonJunior(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have started /// @notice 0xf3f82ac5 bytes4 of this error TooSoonJunior( uint yourTime , uint hitTime ); /// @dev this is TooLateBoomer(), using times /// @param yourTime: should almost always be block.timestamp /// @param hitTime: the time you should have ended /// @notice 0x43c540ef bytes4 of this error TooLateBoomer( uint yourTime , uint hitTime ); }
/contracts/lib/20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Library 20 * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for EIP 20 * @custom:change-log Custom errors added above * * Include with 'using Lib20 for Lib20.Token;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Lib20 { struct Token { mapping(address => uint256) balances; mapping(address => mapping(address => uint256)) allowances; uint256 totalSupply; uint8 decimals; string name; string symbol; } error MaxSplaining(string reason); function setName( Token storage token , string memory newName ) internal { token.name = newName; } function getName( Token storage token ) internal view returns (string memory) { return token.name; } function setSymbol( Token storage token , string memory newSymbol ) internal { token.symbol = newSymbol; } function getSymbol( Token storage token ) internal view returns (string memory) { return token.symbol; } function setDecimals( Token storage token , uint8 newDecimals ) internal { token.decimals = newDecimals; } function getDecimals( Token storage token ) internal view returns (uint8) { return token.decimals; } function getTotalSupply( Token storage token ) internal view returns (uint256) { return token.totalSupply; } function getBalanceOf( Token storage token , address owner ) internal view returns (uint256) { return token.balances[owner]; } function doTransfer( Token storage token , address from , address to , uint256 value ) internal returns (bool success) { uint256 fromBal = getBalanceOf(token, from); if (value > fromBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[from] -= value; token.balances[to] += value; } return true; } function getAllowance( Token storage token , address owner , address spender ) internal view returns (uint256) { return token.allowances[owner][spender]; } function setApprove( Token storage token , address owner , address spender , uint256 amount ) internal returns (bool) { token.allowances[owner][spender] = amount; return true; } function mint( Token storage token , address account , uint256 amount ) internal { if (account == address(0)) { revert MaxSplaining({ reason: "Max20:2" }); } token.totalSupply += amount; unchecked { token.balances[account] += amount; } } function burn( Token storage token , address account , uint256 amount ) internal returns (bool) { uint256 accountBal = getBalanceOf(token, account); if (amount > accountBal) { revert MaxSplaining({ reason: "Max20:1" }); } unchecked { token.balances[account] = accountBal - amount; token.totalSupply -= amount; } return true; } }
/contracts/lib/Roles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: Roles.sol * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library for MaxAcess.sol * @custom:error-code Roles:1 User has role already * @custom:error-code Roles:2 User does not have role to revoke * @custom:change-log custom errors added above * @custom:change-log cleaned up variables * @custom:change-log internal -> internal/internal * * Include with 'using Roles for Roles.Role;' */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; library Roles { bytes4 constant internal DEVS = 0xca4b208b; bytes4 constant internal OWNERS = 0x8da5cb5b; bytes4 constant internal ADMIN = 0xf851a440; struct Role { mapping(address => mapping(bytes4 => bool)) bearer; address owner; address developer; address admin; } event RoleChanged(bytes4 _role, address _user, bool _status); event AdminTransferred(address indexed previousAdmin, address indexed newAdmin); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event DeveloperTransferred(address indexed previousDeveloper, address indexed newDeveloper); error Unauthorized(); error MaxSplaining(string reason); function add( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:1" }); } role.bearer[account][userRole] = true; emit RoleChanged(userRole, account, true); } function remove( Role storage role , bytes4 userRole , address account ) internal { if (account == address(0)) { revert Unauthorized(); } else if (!has(role, userRole, account)) { revert MaxSplaining({ reason: "Roles:2" }); } role.bearer[account][userRole] = false; emit RoleChanged(userRole, account, false); } function has( Role storage role , bytes4 userRole , address account ) internal view returns (bool) { if (account == address(0)) { revert Unauthorized(); } return role.bearer[account][userRole]; } function setAdmin( Role storage role , address account ) internal { if (has(role, ADMIN, account)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setDeveloper( Role storage role , address account ) internal { if (has(role, DEVS, account)) { address old = role.developer; role.developer = account; emit DeveloperTransferred(old, role.developer); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function setOwner( Role storage role , address account ) internal { if (has(role, OWNERS, account)) { address old = role.owner; role.owner = account; emit OwnershipTransferred(old, role.owner); } else if (account == address(0)) { address old = role.admin; role.admin = account; emit AdminTransferred(old, role.admin); } else { revert Unauthorized(); } } function getAdmin( Role storage role ) internal view returns (address) { return role.admin; } function getDeveloper( Role storage role ) internal view returns (address) { return role.developer; } function getOwner( Role storage role ) internal view returns (address) { return role.owner; } }
/contracts/lib/Safe20.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP] Safe ERC 20 Library * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Library makes use of bool success on transfer, transferFrom and approve of EIP 20 */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >= 0.8.0 < 0.9.0; import "../eip/20/IERC20.sol"; library Safe20 { error MaxSplaining(string reason); function safeTransfer( IERC20 token , address to , uint256 amount ) internal { if (!token.transfer(to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transfer failed" }); } } function safeTransferFrom( IERC20 token , address from , address to , uint256 amount ) internal { if (!token.transferFrom(from, to, amount)) { revert MaxSplaining({ reason: "Safe20: token.transferFrom failed" }); } } function safeApprove( IERC20 token , address spender , uint256 amount ) internal { if (!token.approve(spender, amount)) { revert MaxSplaining({ reason: "Safe20: token.approve failed" }); } } }
/contracts/lz/ILayerZeroEndpoint.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroEndpoint.sol * @author: LayerZero * @notice: Interface for LayerZeroEndpoint * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; import "./ILayerZeroUserApplicationConfig.sol"; interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig { // @notice send a LayerZero message to the specified address at a LayerZero endpoint. // @param _dstChainId - the destination chain identifier // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains // @param _payload - a custom bytes payload to send to the destination contract // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination function send( uint16 _dstChainId , bytes calldata _destination , bytes calldata _payload , address payable _refundAddress , address _zroPaymentAddress , bytes calldata _adapterParams ) external payable; // @notice used by the messaging library to publish verified payload // @param _srcChainId - the source chain identifier // @param _srcAddress - the source contract (as bytes) at the source chain // @param _dstAddress - the address on destination chain // @param _nonce - the unbound message ordering nonce // @param _gasLimit - the gas limit for external contract execution // @param _payload - verified payload to send to the destination contract function receivePayload( uint16 _srcChainId , bytes calldata _srcAddress , address _dstAddress , uint64 _nonce , uint _gasLimit , bytes calldata _payload ) external; // @notice get the inboundNonce of a receiver from a source chain which could be EVM or non-EVM chain // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function getInboundNonce( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (uint64); // @notice get the outboundNonce from this source chain which, consequently, is always an EVM // @param _srcAddress - the source chain contract address function getOutboundNonce( uint16 _dstChainId , address _srcAddress ) external view returns (uint64); // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery // @param _dstChainId - the destination chain identifier // @param _userApplication - the user app address on this EVM chain // @param _payload - the custom message to send over LayerZero // @param _payInZRO - if false, user app pays the protocol fee in native token // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain function estimateFees( uint16 _dstChainId , address _userApplication , bytes calldata _payload , bool _payInZRO , bytes calldata _adapterParam ) external view returns ( uint nativeFee , uint zroFee); // @notice get this Endpoint's immutable source identifier function getChainId() external view returns (uint16); // @notice the interface to retry failed message on this Endpoint destination // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address // @param _payload - the payload to be retried function retryPayload( uint16 _srcChainId , bytes calldata _srcAddress , bytes calldata _payload ) external; // @notice query if any STORED payload (message blocking) at the endpoint. // @param _srcChainId - the source chain identifier // @param _srcAddress - the source chain contract address function hasStoredPayload( uint16 _srcChainId , bytes calldata _srcAddress ) external view returns (bool); // @notice query if the _libraryAddress is valid for sending msgs. // @param _userApplication - the user app address on this EVM chain function getSendLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the _libraryAddress is valid for receiving msgs. // @param _userApplication - the user app address on this EVM chain function getReceiveLibraryAddress( address _userApplication ) external view returns (address); // @notice query if the non-reentrancy guard for send() is on // @return true if the guard is on. false otherwise function isSendingPayload() external view returns (bool); // @notice query if the non-reentrancy guard for receive() is on // @return true if the guard is on. false otherwise function isReceivingPayload() external view returns (bool); // @notice get the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _userApplication - the contract address of the user application // @param _configType - type of configuration. every messaging library has its own convention. function getConfig( uint16 _version , uint16 _chainId , address _userApplication , uint _configType ) external view returns (bytes memory); // @notice get the send() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getSendVersion( address _userApplication ) external view returns (uint16); // @notice get the lzReceive() LayerZero messaging library version // @param _userApplication - the contract address of the user application function getReceiveVersion( address _userApplication ) external view returns (uint16); }
/contracts/lz/ILayerZeroReceiver.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroReceiver.sol * @author: LayerZero * @notice: Interface for LayerZeroReceiver * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroReceiver { // @notice LayerZero endpoint will invoke this function to deliver the message on the destination // @param _srcChainId - the source endpoint identifier // @param _srcAddress - the source sending contract address from the source chain // @param _nonce - the ordered message nonce // @param _payload - the signed payload is the UA bytes has encoded to be sent function lzReceive( uint16 _srcChainId , bytes calldata _srcAddress , uint64 _nonce , bytes calldata _payload ) external; }
/contracts/lz/ILayerZeroUserApplicationConfig.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: ILayerZeroUserApplicationConfig.sol * @author: LayerZero * @notice: Interface for LayerZeroUserApplicationConfig * OG Source: https://etherscan.io/address/0xa74ae2c6fca0cedbaef30a8ceef834b247186bcf#code */ // SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface ILayerZeroUserApplicationConfig { // @notice set the configuration of the LayerZero messaging library of the specified version // @param _version - messaging library version // @param _chainId - the chainId for the pending config change // @param _configType - type of configuration. every messaging library has its own convention. // @param _config - configuration in the bytes. can encode arbitrary content. function setConfig( uint16 _version , uint16 _chainId , uint _configType , bytes calldata _config ) external; // @notice set the send() LayerZero messaging library version to _version // @param _version - new messaging library version function setSendVersion( uint16 _version ) external; // @notice set the lzReceive() LayerZero messaging library version to _version // @param _version - new messaging library version function setReceiveVersion( uint16 _version ) external; // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload // @param _srcChainId - the chainId of the source chain // @param _srcAddress - the contract address of the source contract at the source chain function forceResumeReceive( uint16 _srcChainId , bytes calldata _srcAddress ) external; }
/contracts/modules/access/IMAX173.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: EIP-173: Contract Ownership Standard, MaxFlowO2's extension * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for enhancing EIP-173 * @custom:change-log UUPS Upgradable */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/173/IERC173.sol"; interface IMAX173 is IERC173 { /// @dev This is the classic "EIP-173" method of renouncing onlyOwner() function renounceOwnership() external; /// @dev This accepts the push-pull method of onlyOwner() function acceptOwnership() external; /// @dev This declines the push-pull method of onlyOwner() function declineOwnership() external; /// @dev This starts the push-pull method of onlyOwner() /// @param newOwner: addres of new pending owner role function pushOwnership( address newOwner ) external; }
@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
/contracts/modules/access/IMAXDEV.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Developer Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for onlyDev() role */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IMAXDEV is IERC165 { /// @dev Classic "EIP-173" but for onlyDev() /// @return Developer of contract function developer() external view returns (address); /// @dev This renounces your role as onlyDev() function renounceDeveloper() external; /// @dev Classic "EIP-173" but for onlyDev() /// @param newDeveloper: addres of new pending Developer role function transferDeveloper( address newDeveloper ) external; /// @dev This accepts the push-pull method of onlyDev() function acceptDeveloper() external; /// @dev This declines the push-pull method of onlyDev() function declineDeveloper() external; /// @dev This starts the push-pull method of onlyDev() /// @param newDeveloper: addres of new pending developer role function pushDeveloper( address newDeveloper ) external; }
/contracts/modules/access/IRoles.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: Contract Roles Standard * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess version of Roles */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "../../eip/165/IERC165.sol"; interface IRoles is IERC165 { /// @dev Returns `true` if `account` has been granted `role`. /// @param role: Bytes4 of a role /// @param account: Address to check /// @return bool true/false if account has role function hasRole( bytes4 role , address account ) external view returns (bool); /// @dev Returns the admin role that controls a role /// @param role: Role to check /// @return admin role function getRoleAdmin( bytes4 role ) external view returns (bytes4); /// @dev Grants `role` to `account` /// @param role: Bytes4 of a role /// @param account: account to give role to function grantRole( bytes4 role , address account ) external; /// @dev Revokes `role` from `account` /// @param role: Bytes4 of a role /// @param account: account to revoke role from function revokeRole( bytes4 role , address account ) external; /// @dev Renounces `role` from `account` /// @param role: Bytes4 of a role function renounceRole( bytes4 role ) external; }
/contracts/modules/access/MaxAccess.sol
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+ * .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%## * .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=* * %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#* * *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=: * @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@ * @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+ * -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%* * * @title: [Not an EIP]: MaxFlow's 173/Dev/Roles Interface * @author: Max Flow O2 -> @MaxFlowO2 on bird app/GitHub * @dev Interface for MaxAccess */ // SPDX-License-Identifier: Apache-2.0 /****************************************************************************** * Copyright 2022 Max Flow O2 * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ pragma solidity >=0.8.0 <0.9.0; import "./IMAX173.sol"; import "./IMAXDEV.sol"; import "./IRoles.sol"; interface MaxAccess is IMAX173 , IMAXDEV , IRoles { ///@dev this just imports all 3 and pushes to Implementation }
@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; import "../beacon/IBeaconUpgradeable.sol"; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { function __ERC1967Upgrade_init() internal onlyInitializing { } function __ERC1967Upgrade_init_unchained() internal onlyInitializing { } // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @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 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall( address newImplementation, bytes memory data, bool forceCall ) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS( address newImplementation, bytes memory data, bool forceCall ) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); } catch { revert("ERC1967Upgrade: new implementation is not UUPS"); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @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 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { require(newAdmin != address(0), "ERC1967: new admin is the zero address"); StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); require( AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), "ERC1967: beacon implementation is not a contract" ); StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall( address newBeacon, bytes memory data, bool forceCall ) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; import "../../interfaces/draft-IERC1822Upgradeable.sol"; import "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { function __UUPSUpgradeable_init() internal onlyInitializing { } function __UUPSUpgradeable_init_unchained() internal onlyInitializing { } /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { require(address(this) != __self, "Function must be called through delegatecall"); require(_getImplementation() == __self, "Function must be called through active proxy"); _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate that the this implementation remains valid after an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"error","name":"MaxSplaining","inputs":[{"type":"string","name":"reason","internalType":"string"}]},{"type":"error","name":"MaxSplaining","inputs":[{"type":"string","name":"reason","internalType":"string"}]},{"type":"error","name":"MaxSplaining","inputs":[{"type":"string","name":"reason","internalType":"string"}]},{"type":"error","name":"TooLateBoomer","inputs":[{"type":"uint256","name":"yourTime","internalType":"uint256"},{"type":"uint256","name":"hitTime","internalType":"uint256"}]},{"type":"error","name":"TooSoonJunior","inputs":[{"type":"uint256","name":"yourTime","internalType":"uint256"},{"type":"uint256","name":"hitTime","internalType":"uint256"}]},{"type":"error","name":"Unauthorized","inputs":[]},{"type":"error","name":"Unauthorized","inputs":[]},{"type":"event","name":"AdminChanged","inputs":[{"type":"address","name":"previousAdmin","internalType":"address","indexed":false},{"type":"address","name":"newAdmin","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"_owner","internalType":"address","indexed":true},{"type":"address","name":"_spender","internalType":"address","indexed":true},{"type":"uint256","name":"_value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"BeaconUpgraded","inputs":[{"type":"address","name":"beacon","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"EndpointSet","inputs":[{"type":"address","name":"_endpoint","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"MessageFailed","inputs":[{"type":"uint16","name":"_srcChainId","internalType":"uint16","indexed":false},{"type":"bytes","name":"_srcAddress","internalType":"bytes","indexed":false},{"type":"uint64","name":"_nonce","internalType":"uint64","indexed":false},{"type":"bytes","name":"_payload","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"_from","internalType":"address","indexed":true},{"type":"address","name":"_to","internalType":"address","indexed":true},{"type":"uint256","name":"_value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TrustedRemoteSet","inputs":[{"type":"uint16","name":"_chainId","internalType":"uint16","indexed":false},{"type":"bytes","name":"_trustedRemote","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"Upgraded","inputs":[{"type":"address","name":"implementation","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptDeveloper","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"remaining","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"_spender","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"balance","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"burn","inputs":[{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"burnFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentLZGas","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"declineDeveloper","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"declineOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"developer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"payloadLength","internalType":"uint256"},{"type":"bytes32","name":"payloadHash","internalType":"bytes32"}],"name":"failedMessages","inputs":[{"type":"uint16","name":"","internalType":"uint16"},{"type":"bytes","name":"","internalType":"bytes"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes4","name":"","internalType":"bytes4"}],"name":"getRoleAdmin","inputs":[{"type":"bytes4","name":"role","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes4","name":"role","internalType":"bytes4"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes4","name":"role","internalType":"bytes4"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_admin","internalType":"address"},{"type":"address","name":"_mint","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"lzReceive","inputs":[{"type":"uint16","name":"_srcChainId","internalType":"uint16"},{"type":"bytes","name":"_srcAddress","internalType":"bytes"},{"type":"uint64","name":"_nonce","internalType":"uint64"},{"type":"bytes","name":"_payload","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"onLzReceive","inputs":[{"type":"uint16","name":"_srcChainId","internalType":"uint16"},{"type":"bytes","name":"_srcAddress","internalType":"bytes"},{"type":"uint64","name":"_nonce","internalType":"uint64"},{"type":"bytes","name":"_payload","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pushDeveloper","inputs":[{"type":"address","name":"newDeveloper","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pushOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceDeveloper","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceRole","inputs":[{"type":"bytes4","name":"role","internalType":"bytes4"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"retryMessage","inputs":[{"type":"uint16","name":"_srcChainId","internalType":"uint16"},{"type":"bytes","name":"_srcAddress","internalType":"bytes"},{"type":"uint64","name":"_nonce","internalType":"uint64"},{"type":"bytes","name":"_payload","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes4","name":"role","internalType":"bytes4"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setEndPoint","inputs":[{"type":"address","name":"newEndpoint","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGasForDestinationLzReceive","inputs":[{"type":"uint256","name":"newVal","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTrustedRemote","inputs":[{"type":"uint16","name":"_chainId","internalType":"uint16"},{"type":"bytes","name":"_trustedRemote","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceID","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferDeveloper","inputs":[{"type":"address","name":"newDeveloper","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"success","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"_from","internalType":"address"},{"type":"address","name":"_to","internalType":"address"},{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"_newOwner","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"traverseChains","inputs":[{"type":"uint16","name":"_chainId","internalType":"uint16"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes","name":"","internalType":"bytes"}],"name":"trustedRemoteLookup","inputs":[{"type":"uint16","name":"","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"upgradeTo","inputs":[{"type":"address","name":"newImplementation","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"upgradeToAndCall","inputs":[{"type":"address","name":"newImplementation","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]}]
Contract Creation Code
0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516144ba62000120600039600081816111e40152818161127a015281816117be01528181611854015261194f01526144ba6000f3fe6080604052600436106102db5760003560e01c806366278a6c11610184578063a9059cbb116100d6578063d1deba1f1161008a578063de02cde711610064578063de02cde714610803578063eb8d72b714610823578063f2fde38b1461084357600080fd5b8063d1deba1f146107b0578063d39ce77c146107c3578063dd62ed3e146107e357600080fd5b8063ca4b208b116100bb578063ca4b208b1461075f578063cb40cb491461077d578063cf89fa031461079d57600080fd5b8063a9059cbb1461072a578063ad6d9c171461074a57600080fd5b806379cc679011610138578063943fb87211610112578063943fb872146106e057806395d89b4114610700578063a86ff9601461071557600080fd5b806379cc6790146106235780638da5cb5b146106435780638ee749121461067557600080fd5b8063715018a611610169578063715018a6146105d95780637533d788146105ee57806379ba50971461060e57600080fd5b806366278a6c1461059957806370a08231146105b957600080fd5b806331e26cfd1161023d578063485cc955116101f15780635ba5e9f0116101cb5780635ba5e9f0146105015780636149d8711461055957806364cb4edb1461057957600080fd5b8063485cc955146104b95780634f1ef286146104d957806352d1902d146104ec57600080fd5b806342966c681161022257806342966c681461046457806344faded014610484578063475de12e146104a457600080fd5b806331e26cfd1461042f5780633659cfe61461044457600080fd5b806318160ddd1161029457806323b872dd1161027957806323b872dd146103d85780632bfcf0f2146103f8578063313ce5671461040d57600080fd5b806318160ddd146103995780631c37a822146103b857600080fd5b806306fdde03116102c557806306fdde0314610337578063095ea7b31461035957806310ab94321461037957600080fd5b80621d3567146102e057806301ffc9a714610302575b600080fd5b3480156102ec57600080fd5b506103006102fb366004613a17565b610863565b005b34801561030e57600080fd5b5061032261031d366004613acc565b610aa1565b60405190151581526020015b60405180910390f35b34801561034357600080fd5b5061034c610c6a565b60405161032e9190613b37565b34801561036557600080fd5b50610322610374366004613b5f565b610c7b565b34801561038557600080fd5b50610322610394366004613b8b565b610cdd565b3480156103a557600080fd5b506003545b60405190815260200161032e565b3480156103c457600080fd5b506103006103d3366004613a17565b610cf2565b3480156103e457600080fd5b506103226103f3366004613bc2565b610d4e565b34801561040457600080fd5b50610300611080565b34801561041957600080fd5b5060045460405160ff909116815260200161032e565b34801561043b57600080fd5b50610300611163565b34801561045057600080fd5b5061030061045f366004613c03565b6111da565b34801561047057600080fd5b5061032261047f366004613c20565b611374565b34801561049057600080fd5b5061030061049f366004613b8b565b611494565b3480156104b057600080fd5b50600f546103aa565b3480156104c557600080fd5b506103006104d4366004613c39565b611582565b6103006104e7366004613c57565b6117b4565b3480156104f857600080fd5b506103aa611942565b34801561050d57600080fd5b5061052861051c366004613acc565b506303e1469160e61b90565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161032e565b34801561056557600080fd5b50610300610574366004613c03565b611a07565b34801561058557600080fd5b50610300610594366004613c03565b611a7e565b3480156105a557600080fd5b506103006105b4366004613acc565b611b2c565b3480156105c557600080fd5b506103aa6105d4366004613c03565b611b63565b3480156105e557600080fd5b50610300611b81565b3480156105fa57600080fd5b5061034c610609366004613ca7565b611c04565b34801561061a57600080fd5b50610300611c9e565b34801561062f57600080fd5b5061032261063e366004613b5f565b611d4c565b34801561064f57600080fd5b506008546001600160a01b03165b6040516001600160a01b03909116815260200161032e565b34801561068157600080fd5b506106cb610690366004613cc2565b600d60209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b6040805192835260208301919091520161032e565b3480156106ec57600080fd5b506103006106fb366004613c20565b612031565b34801561070c57600080fd5b5061034c612067565b34801561072157600080fd5b50610300612073565b34801561073657600080fd5b50610322610745366004613b5f565b6120ea565b34801561075657600080fd5b50610300612274565b34801561076b57600080fd5b506009546001600160a01b031661065d565b34801561078957600080fd5b50610300610798366004613c03565b6122f7565b6103006107ab366004613d19565b61238a565b6103006107be366004613d7e565b612674565b3480156107cf57600080fd5b506103006107de366004613c03565b612810565b3480156107ef57600080fd5b506103aa6107fe366004613c39565b612887565b34801561080f57600080fd5b5061030061081e366004613b8b565b6128b4565b34801561082f57600080fd5b5061030061083e366004613e0a565b6129b3565b34801561084f57600080fd5b5061030061085e366004613c03565b612a36565b600c546001600160a01b031633146108c357604051630330dbc960e11b815260206004820152600560248201527f4e42523a3100000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61ffff84166000908152600e6020526040902080546108e190613e5d565b90508351141580610921575061ffff84166000908152600e602052604090819020905161090e9190613eaa565b6040518091039020838051906020012014155b1561096f57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3200000000000000000000000000000000000000000000000000000060448201526064016108ba565b6040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a822906109b1908790879087908790600401613f20565b600060405180830381600087803b1580156109cb57600080fd5b505af19250505080156109dc575060015b610a9b576040518060400160405280825181526020018280519060200120815250600d60008661ffff1661ffff16815260200190815260200160002084604051610a269190613f6a565b90815260408051918290036020908101832067ffffffffffffffff8716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d90610a92908690869086908690613f20565b60405180910390a15b50505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7f5828d0000000000000000000000000000000000000000000000000000000001480610b3457507fffffffff0000000000000000000000000000000000000000000000000000000082167f7319562d00000000000000000000000000000000000000000000000000000000145b80610b8057507fffffffff0000000000000000000000000000000000000000000000000000000082167f78bab63900000000000000000000000000000000000000000000000000000000145b80610bcc57507fffffffff0000000000000000000000000000000000000000000000000000000082167fb7d1e49900000000000000000000000000000000000000000000000000000000145b80610c1857507fffffffff0000000000000000000000000000000000000000000000000000000082167f3b5a0bf800000000000000000000000000000000000000000000000000000000145b80610c6457507fffffffff0000000000000000000000000000000000000000000000000000000082167f942e8b2200000000000000000000000000000000000000000000000000000000145b92915050565b6060610c766001612ae4565b905090565b3360008181526002602090815260408083206001600160a01b0387168085529083529281902085905551848152600193917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a392915050565b6000610ceb60078484612b7a565b9392505050565b333014610d4257604051630330dbc960e11b815260206004820152600560248201527f4e42523a3300000000000000000000000000000000000000000000000000000060448201526064016108ba565b610a9b84848484612c09565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152600090819030906370a0823190602401602060405180830381865afa158015610db0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd49190613f86565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152336024820152909150600090309063dd62ed3e90604401602060405180830381865afa158015610e3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e619190613f86565b90506001600160a01b0386161580610e8057506001600160a01b038516155b15610ece57604051630330dbc960e11b815260206004820152601960248201527f4d617832303a20746f2f66726f6d20616464726573732830290000000000000060448201526064016108ba565b81841115610f1f57604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016108ba565b80841115610f9657604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c7565000000000000000000000000000000000000000000000000000000000060648201526084016108ba565b610fa36001878787612c7a565b9250846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051610fea91815260200190565b60405180910390a361102f86336110018785613fce565b6001600160a01b03928316600090815260026020908152604080832095909416825293909352912055600190565b50336001600160a01b0387167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256110668785613fce565b60405190815260200160405180910390a350509392505050565b7fca4b208a000000000000000000000000000000000000000000000000000000006110ad60078233612b7a565b806110c657506110c660076303e1469160e61b33612b7a565b15611131576110f760077fca4b208b0000000000000000000000000000000000000000000000000000000033612d1d565b611102600733612e47565b61112e60077fca4b208a0000000000000000000000000000000000000000000000000000000033612f5f565b50565b6040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fca4b208a0000000000000000000000000000000000000000000000000000000061119060078233612b7a565b806111a957506111a960076303e1469160e61b33612b7a565b156111315761112e60077fca4b208a0000000000000000000000000000000000000000000000000000000033612f5f565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036112785760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016108ba565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166112d37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b03161461134f5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016108ba565b6113588161307e565b6040805160008082526020820190925261112e918391906130e1565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819030906370a0823190602401602060405180830381865afa1580156113cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f19190613f86565b90508083111561144457604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016108ba565b61145060013385613281565b506040518381526001925060009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35b50919050565b816114a160078233612b7a565b806114ba57506114ba60076303e1469160e61b33612b7a565b15611131577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061155057507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b1561157657336001600160a01b038316036111315761157160078484612f5f565b505050565b61157160078484612f5f565b600054610100900460ff16158080156115a25750600054600160ff909116105b806115bc5750303b1580156115bc575060005460ff166001145b61162e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016108ba565b6000805460ff19166001179055801561166e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6116e56040518060400160405280600681526020017f78534852415000000000000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f785348524150000000000000000000000000000000000000000000000000000081525060128661331e565b6116ed61344c565b611702600183681b1ae4d6e2ef5000006134cb565b604051681b1ae4d6e2ef50000081526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3801561157157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036118525760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016108ba565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166118ad7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146119295760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016108ba565b6119328261307e565b61193e828260016130e1565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146119e25760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ba565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b7fca4b208b00000000000000000000000000000000000000000000000000000000611a3460078233612b7a565b80611a4d5750611a4d60076303e1469160e61b33612b7a565b156111315761193e60077fca4b208a0000000000000000000000000000000000000000000000000000000084612d1d565b7fca4b208b00000000000000000000000000000000000000000000000000000000611aab60078233612b7a565b80611ac45750611ac460076303e1469160e61b33612b7a565b1561113157611af560077fca4b208b0000000000000000000000000000000000000000000000000000000084612d1d565b611b00600783612e47565b61193e60077fca4b208b0000000000000000000000000000000000000000000000000000000033612f5f565b80611b3960078233612b7a565b80611b525750611b5260076303e1469160e61b33612b7a565b156111315761193e60078333612f5f565b6001600160a01b038116600090815260016020526040812054610c64565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000611bae60078233612b7a565b80611bc75750611bc760076303e1469160e61b33612b7a565b1561113157611bd86007600061355f565b61112e60077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612f5f565b600e6020526000908152604090208054611c1d90613e5d565b80601f0160208091040260200160405190810160405280929190818152602001828054611c4990613e5d565b8015611c965780601f10611c6b57610100808354040283529160200191611c96565b820191906000526020600020905b815481529060010190602001808311611c7957829003601f168201915b505050505081565b7f8da5cb5a00000000000000000000000000000000000000000000000000000000611ccb60078233612b7a565b80611ce45750611ce460076303e1469160e61b33612b7a565b1561113157611d1560077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612d1d565b611d2060073361355f565b61112e60077f8da5cb5a0000000000000000000000000000000000000000000000000000000033612f5f565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152600090819030906370a0823190602401602060405180830381865afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd29190613f86565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152336024820152909150600090309063dd62ed3e90604401602060405180830381865afa158015611e3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5f9190613f86565b90506001600160a01b038516611eb857604051630330dbc960e11b815260206004820152601660248201527f4d617832303a2066726f6d20616464726573732830290000000000000000000060448201526064016108ba565b81841115611f0957604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016108ba565b80841115611f8057604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c7565000000000000000000000000000000000000000000000000000000000060648201526084016108ba565b611f8c60018686613281565b50604051848152600193506000906001600160a01b038716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611fe185336110018785613fce565b50336001600160a01b0386167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256120188785613fce565b60405190815260200160405180910390a3505092915050565b61205d60077fca4b208b0000000000000000000000000000000000000000000000000000000033612b7a565b1561113157600f55565b6060610c7660016135fc565b7f8da5cb5a000000000000000000000000000000000000000000000000000000006120a060078233612b7a565b806120b957506120b960076303e1469160e61b33612b7a565b156111315761112e60077f8da5cb5a0000000000000000000000000000000000000000000000000000000033612f5f565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819030906370a0823190602401602060405180830381865afa158015612143573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121679190613f86565b90506001600160a01b0384166121c057604051630330dbc960e11b815260206004820152601460248201527f4d617832303a20746f206164647265737328302900000000000000000000000060448201526064016108ba565b8083111561221157604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016108ba565b61221e6001338686612c7a565b9150836001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161226591815260200190565b60405180910390a35092915050565b7fca4b208b000000000000000000000000000000000000000000000000000000006122a160078233612b7a565b806122ba57506122ba60076303e1469160e61b33612b7a565b15611131576122cb60076000612e47565b61112e60077fca4b208b0000000000000000000000000000000000000000000000000000000033612f5f565b61232360077fca4b208b0000000000000000000000000000000000000000000000000000000033612b7a565b1561113157600c80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f87bf030d6c6aa55db1e81d52f84962fc04ce1d477e64e50d57d3a91c52296f9390600090a250565b33600090815260016020526040902054808211156123d4576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61ffff83166000908152600e6020526040902080546123f290613e5d565b905060000361244457604051630330dbc960e11b815260206004820152601160248201527f546f6b656e3a205452206e6f742073657400000000000000000000000000000060448201526064016108ba565b61245060013384613281565b5060405182815260009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a360408051336020820152808201849052815180820383018152606082018352600f547e0100000000000000000000000000000000000000000000000000000000000060808401526082808401919091528351808403909101815260a2830193849052600c547f40a7bb100000000000000000000000000000000000000000000000000000000090945290926001926000916001600160a01b0316906340a7bb1090612540908a90309089908790899060a601613fe1565b6040805180830381865afa15801561255c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125809190614033565b509050348111156125d457604051630330dbc960e11b815260206004820152601660248201527f546f6b656e3a206d65737361676520666565206c6f770000000000000000000060448201526064016108ba565b600c5461ffff88166000908152600e602052604080822090517fc58031000000000000000000000000000000000000000000000000000000000081526001600160a01b039093169263c5803100923492612639928d928b913391908b90600401614057565b6000604051808303818588803b15801561265257600080fd5b505af1158015612666573d6000803e3d6000fd5b505050505050505050505050565b61ffff85166000908152600d60205260408082209051612695908790613f6a565b908152604080516020928190038301902067ffffffffffffffff8716600090815292529020600181015490915061270f57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3400000000000000000000000000000000000000000000000000000060448201526064016108ba565b80548214158061273a57508060010154838360405161272f92919061413c565b604051809103902014155b1561278857604051630330dbc960e11b815260206004820152600560248201527f4e42523a3500000000000000000000000000000000000000000000000000000060448201526064016108ba565b600080825560018201556040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a822906127d69089908990899089908990600401614177565b600060405180830381600087803b1580156127f057600080fd5b505af1158015612804573d6000803e3d6000fd5b50505050505050505050565b7f8da5cb5b0000000000000000000000000000000000000000000000000000000061283d60078233612b7a565b80612856575061285660076303e1469160e61b33612b7a565b156111315761193e60077f8da5cb5a0000000000000000000000000000000000000000000000000000000084612d1d565b6001600160a01b038083166000908152600260209081526040808320938516835292905290812054610ceb565b816128c160078233612b7a565b806128da57506128da60076303e1469160e61b33612b7a565b15611131577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061297057507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b156129a7576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157160078484612d1d565b6129df60077fca4b208b0000000000000000000000000000000000000000000000000000000033612b7a565b156111315761ffff83166000908152600e60205260409020612a02828483614205565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b80567488383836040516117a793929190614302565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000612a6360078233612b7a565b80612a7c5750612a7c60076303e1469160e61b33612b7a565b1561113157612aad60077f8da5cb5b0000000000000000000000000000000000000000000000000000000084612d1d565b612ab860078361355f565b61193e60077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612f5f565b6060816004018054612af590613e5d565b80601f0160208091040260200160405190810160405280929190818152602001828054612b2190613e5d565b8015612b6e5780601f10612b4357610100808354040283529160200191612b6e565b820191906000526020600020905b815481529060010190602001808311612b5157829003601f168201915b50505050509050919050565b60006001600160a01b038216612bbc576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082207fffffffff000000000000000000000000000000000000000000000000000000009390931682529190925290205460ff1690565b60008082806020019051810190612c209190614320565b9092509050612c31600183836134cb565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050505050565b6001600160a01b03831660009081526020859052604081205480831115612ce457604051630330dbc960e11b815260206004820152600760248201527f4d617832303a310000000000000000000000000000000000000000000000000060448201526064016108ba565b50506001600160a01b03808416600090815260208690526040808220805485900390559184168152208054820190556001949350505050565b6001600160a01b038116612d5d576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d68838383612b7a565b15612db657604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a310000000000000000000000000000000000000000000000000060448201526064016108ba565b6001600160a01b0381166000818152602085815260408083207fffffffff00000000000000000000000000000000000000000000000000000000871680855290835292819020805460ff19166001908117909155815193845291830193909352918101919091527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060016117a7565b612e72827fca4b208b0000000000000000000000000000000000000000000000000000000083612b7a565b15612ee4576002820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6001600160a01b038116611131576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b038116612f9f576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612faa838383612b7a565b612ff757604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a320000000000000000000000000000000000000000000000000060448201526064016108ba565b6001600160a01b0381166000818152602085815260408083207fffffffff000000000000000000000000000000000000000000000000000000008716808552908352818420805460ff19169055815190815291820193909352918201527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060016117a7565b6303e1469160e61b61309260078233612b7a565b806130ab57506130ab60076303e1469160e61b33612b7a565b61193e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613114576115718361360d565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561316e575060408051601f3d908101601f1916820190925261316b91810190613f86565b60015b6131e05760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f74205555505300000000000000000000000000000000000060648201526084016108ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146132755760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c6555554944000000000000000000000000000000000000000000000060648201526084016108ba565b506115718383836136e3565b6001600160a01b038216600090815260208490526040812054808311156132eb57604051630330dbc960e11b815260206004820152600760248201527f4d617832303a310000000000000000000000000000000000000000000000000060448201526064016108ba565b6001600160a01b038416600090815260208690526040902090839003905550600283018054829003905560019392505050565b600054610100900460ff1661339b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016108ba565b6133a6600185613708565b6133b1600184613716565b6004805460ff191660ff84161790556133d360076303e1469160e61b83612d1d565b6133de600782613724565b61340a60077fca4b208b0000000000000000000000000000000000000000000000000000000083612d1d565b613415600782612e47565b61344160077f8da5cb5b0000000000000000000000000000000000000000000000000000000083612d1d565b610a9b60078261355f565b600054610100900460ff166134c95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016108ba565b565b6001600160a01b03821661352257604051630330dbc960e11b815260206004820152600760248201527f4d617832303a320000000000000000000000000000000000000000000000000060448201526064016108ba565b80836002016000828254613536919061434e565b90915550506001600160a01b039091166000908152602092909252604090912080549091019055565b61358a827f8da5cb5b0000000000000000000000000000000000000000000000000000000083612b7a565b15612ee4576001820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6060816005018054612af590613e5d565b6001600160a01b0381163b61368a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016108ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6136ec836137a8565b6000825111806136f95750805b1561157157610a9b83836137e8565b600482016115718282614361565b600582016115718282614361565b613736826303e1469160e61b83612b7a565b15612ee4576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6137b18161360d565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6138675760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016108ba565b600080846001600160a01b0316846040516138829190613f6a565b600060405180830381855af49150503d80600081146138bd576040519150601f19603f3d011682016040523d82523d6000602084013e6138c2565b606091505b50915091506138ea828260405180606001604052806027815260200161445e602791396138f3565b95945050505050565b60608315613902575081610ceb565b8251156139125782518084602001fd5b8160405162461bcd60e51b81526004016108ba9190613b37565b803561ffff8116811461393e57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261398357600080fd5b813567ffffffffffffffff8082111561399e5761399e613943565b604051601f8301601f19908116603f011681019082821181831017156139c6576139c6613943565b816040528381528660208588010111156139df57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff8116811461393e57600080fd5b60008060008060808587031215613a2d57600080fd5b613a368561392c565b9350602085013567ffffffffffffffff80821115613a5357600080fd5b613a5f88838901613972565b9450613a6d604088016139ff565b93506060870135915080821115613a8357600080fd5b50613a9087828801613972565b91505092959194509250565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461393e57600080fd5b600060208284031215613ade57600080fd5b610ceb82613a9c565b60005b83811015613b02578181015183820152602001613aea565b50506000910152565b60008151808452613b23816020860160208601613ae7565b601f01601f19169290920160200192915050565b602081526000610ceb6020830184613b0b565b6001600160a01b038116811461112e57600080fd5b60008060408385031215613b7257600080fd5b8235613b7d81613b4a565b946020939093013593505050565b60008060408385031215613b9e57600080fd5b613ba783613a9c565b91506020830135613bb781613b4a565b809150509250929050565b600080600060608486031215613bd757600080fd5b8335613be281613b4a565b92506020840135613bf281613b4a565b929592945050506040919091013590565b600060208284031215613c1557600080fd5b8135610ceb81613b4a565b600060208284031215613c3257600080fd5b5035919050565b60008060408385031215613c4c57600080fd5b8235613ba781613b4a565b60008060408385031215613c6a57600080fd5b8235613c7581613b4a565b9150602083013567ffffffffffffffff811115613c9157600080fd5b613c9d85828601613972565b9150509250929050565b600060208284031215613cb957600080fd5b610ceb8261392c565b600080600060608486031215613cd757600080fd5b613ce08461392c565b9250602084013567ffffffffffffffff811115613cfc57600080fd5b613d0886828701613972565b925050604084013590509250925092565b60008060408385031215613d2c57600080fd5b613b7d8361392c565b60008083601f840112613d4757600080fd5b50813567ffffffffffffffff811115613d5f57600080fd5b602083019150836020828501011115613d7757600080fd5b9250929050565b600080600080600060808688031215613d9657600080fd5b613d9f8661392c565b9450602086013567ffffffffffffffff80821115613dbc57600080fd5b613dc889838a01613972565b9550613dd6604089016139ff565b94506060880135915080821115613dec57600080fd5b50613df988828901613d35565b969995985093965092949392505050565b600080600060408486031215613e1f57600080fd5b613e288461392c565b9250602084013567ffffffffffffffff811115613e4457600080fd5b613e5086828701613d35565b9497909650939450505050565b600181811c90821680613e7157607f821691505b60208210810361148e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000808354613eb881613e5d565b60018281168015613ed05760018114613ee557613f14565b60ff1984168752821515830287019450613f14565b8760005260208060002060005b85811015613f0b5781548a820152908401908201613ef2565b50505082870194505b50929695505050505050565b61ffff85168152608060208201526000613f3d6080830186613b0b565b67ffffffffffffffff851660408401528281036060840152613f5f8185613b0b565b979650505050505050565b60008251613f7c818460208701613ae7565b9190910192915050565b600060208284031215613f9857600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c6457610c64613f9f565b61ffff861681526001600160a01b038516602082015260a06040820152600061400d60a0830186613b0b565b841515606084015282810360808401526140278185613b0b565b98975050505050505050565b6000806040838503121561404657600080fd5b505080516020909101519092909150565b61ffff871681526000602060c0818401526000885461407581613e5d565b8060c087015260e060018084166000811461409757600181146140b1576140df565b60ff198516838a01528284151560051b8a010195506140df565b8d6000528660002060005b858110156140d75781548b82018601529083019088016140bc565b8a0184019650505b505050505083810360408501526140f68189613b0b565b91505061410e60608401876001600160a01b03169052565b6001600160a01b038516608084015282810360a084015261412f8185613b0b565b9998505050505050505050565b8183823760009101908152919050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b61ffff861681526080602082015260006141946080830187613b0b565b67ffffffffffffffff86166040840152828103606084015261402781858761414c565b601f82111561157157600081815260208120601f850160051c810160208610156141de5750805b601f850160051c820191505b818110156141fd578281556001016141ea565b505050505050565b67ffffffffffffffff83111561421d5761421d613943565b6142318361422b8354613e5d565b836141b7565b6000601f841160018114614283576000851561424d5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556142fb565b600083815260209020601f19861690835b828110156142b45786850135825560209485019460019092019101614294565b50868210156142ef577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff841681526040602082015260006138ea60408301848661414c565b6000806040838503121561433357600080fd5b825161433e81613b4a565b6020939093015192949293505050565b80820180821115610c6457610c64613f9f565b815167ffffffffffffffff81111561437b5761437b613943565b61438f816143898454613e5d565b846141b7565b602080601f8311600181146143e257600084156143ac5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556141fd565b600085815260208120601f198616915b82811015614411578886015182559484019460019091019084016143f2565b508582101561444d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b75f7f57a16c61f5a05023cfdb3ef1df86b8fe6f3bde5191fd22c41dcebddc4064736f6c63430008130033
Deployed ByteCode
0x6080604052600436106102db5760003560e01c806366278a6c11610184578063a9059cbb116100d6578063d1deba1f1161008a578063de02cde711610064578063de02cde714610803578063eb8d72b714610823578063f2fde38b1461084357600080fd5b8063d1deba1f146107b0578063d39ce77c146107c3578063dd62ed3e146107e357600080fd5b8063ca4b208b116100bb578063ca4b208b1461075f578063cb40cb491461077d578063cf89fa031461079d57600080fd5b8063a9059cbb1461072a578063ad6d9c171461074a57600080fd5b806379cc679011610138578063943fb87211610112578063943fb872146106e057806395d89b4114610700578063a86ff9601461071557600080fd5b806379cc6790146106235780638da5cb5b146106435780638ee749121461067557600080fd5b8063715018a611610169578063715018a6146105d95780637533d788146105ee57806379ba50971461060e57600080fd5b806366278a6c1461059957806370a08231146105b957600080fd5b806331e26cfd1161023d578063485cc955116101f15780635ba5e9f0116101cb5780635ba5e9f0146105015780636149d8711461055957806364cb4edb1461057957600080fd5b8063485cc955146104b95780634f1ef286146104d957806352d1902d146104ec57600080fd5b806342966c681161022257806342966c681461046457806344faded014610484578063475de12e146104a457600080fd5b806331e26cfd1461042f5780633659cfe61461044457600080fd5b806318160ddd1161029457806323b872dd1161027957806323b872dd146103d85780632bfcf0f2146103f8578063313ce5671461040d57600080fd5b806318160ddd146103995780631c37a822146103b857600080fd5b806306fdde03116102c557806306fdde0314610337578063095ea7b31461035957806310ab94321461037957600080fd5b80621d3567146102e057806301ffc9a714610302575b600080fd5b3480156102ec57600080fd5b506103006102fb366004613a17565b610863565b005b34801561030e57600080fd5b5061032261031d366004613acc565b610aa1565b60405190151581526020015b60405180910390f35b34801561034357600080fd5b5061034c610c6a565b60405161032e9190613b37565b34801561036557600080fd5b50610322610374366004613b5f565b610c7b565b34801561038557600080fd5b50610322610394366004613b8b565b610cdd565b3480156103a557600080fd5b506003545b60405190815260200161032e565b3480156103c457600080fd5b506103006103d3366004613a17565b610cf2565b3480156103e457600080fd5b506103226103f3366004613bc2565b610d4e565b34801561040457600080fd5b50610300611080565b34801561041957600080fd5b5060045460405160ff909116815260200161032e565b34801561043b57600080fd5b50610300611163565b34801561045057600080fd5b5061030061045f366004613c03565b6111da565b34801561047057600080fd5b5061032261047f366004613c20565b611374565b34801561049057600080fd5b5061030061049f366004613b8b565b611494565b3480156104b057600080fd5b50600f546103aa565b3480156104c557600080fd5b506103006104d4366004613c39565b611582565b6103006104e7366004613c57565b6117b4565b3480156104f857600080fd5b506103aa611942565b34801561050d57600080fd5b5061052861051c366004613acc565b506303e1469160e61b90565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161032e565b34801561056557600080fd5b50610300610574366004613c03565b611a07565b34801561058557600080fd5b50610300610594366004613c03565b611a7e565b3480156105a557600080fd5b506103006105b4366004613acc565b611b2c565b3480156105c557600080fd5b506103aa6105d4366004613c03565b611b63565b3480156105e557600080fd5b50610300611b81565b3480156105fa57600080fd5b5061034c610609366004613ca7565b611c04565b34801561061a57600080fd5b50610300611c9e565b34801561062f57600080fd5b5061032261063e366004613b5f565b611d4c565b34801561064f57600080fd5b506008546001600160a01b03165b6040516001600160a01b03909116815260200161032e565b34801561068157600080fd5b506106cb610690366004613cc2565b600d60209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b6040805192835260208301919091520161032e565b3480156106ec57600080fd5b506103006106fb366004613c20565b612031565b34801561070c57600080fd5b5061034c612067565b34801561072157600080fd5b50610300612073565b34801561073657600080fd5b50610322610745366004613b5f565b6120ea565b34801561075657600080fd5b50610300612274565b34801561076b57600080fd5b506009546001600160a01b031661065d565b34801561078957600080fd5b50610300610798366004613c03565b6122f7565b6103006107ab366004613d19565b61238a565b6103006107be366004613d7e565b612674565b3480156107cf57600080fd5b506103006107de366004613c03565b612810565b3480156107ef57600080fd5b506103aa6107fe366004613c39565b612887565b34801561080f57600080fd5b5061030061081e366004613b8b565b6128b4565b34801561082f57600080fd5b5061030061083e366004613e0a565b6129b3565b34801561084f57600080fd5b5061030061085e366004613c03565b612a36565b600c546001600160a01b031633146108c357604051630330dbc960e11b815260206004820152600560248201527f4e42523a3100000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61ffff84166000908152600e6020526040902080546108e190613e5d565b90508351141580610921575061ffff84166000908152600e602052604090819020905161090e9190613eaa565b6040518091039020838051906020012014155b1561096f57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3200000000000000000000000000000000000000000000000000000060448201526064016108ba565b6040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a822906109b1908790879087908790600401613f20565b600060405180830381600087803b1580156109cb57600080fd5b505af19250505080156109dc575060015b610a9b576040518060400160405280825181526020018280519060200120815250600d60008661ffff1661ffff16815260200190815260200160002084604051610a269190613f6a565b90815260408051918290036020908101832067ffffffffffffffff8716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d90610a92908690869086908690613f20565b60405180910390a15b50505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7f5828d0000000000000000000000000000000000000000000000000000000001480610b3457507fffffffff0000000000000000000000000000000000000000000000000000000082167f7319562d00000000000000000000000000000000000000000000000000000000145b80610b8057507fffffffff0000000000000000000000000000000000000000000000000000000082167f78bab63900000000000000000000000000000000000000000000000000000000145b80610bcc57507fffffffff0000000000000000000000000000000000000000000000000000000082167fb7d1e49900000000000000000000000000000000000000000000000000000000145b80610c1857507fffffffff0000000000000000000000000000000000000000000000000000000082167f3b5a0bf800000000000000000000000000000000000000000000000000000000145b80610c6457507fffffffff0000000000000000000000000000000000000000000000000000000082167f942e8b2200000000000000000000000000000000000000000000000000000000145b92915050565b6060610c766001612ae4565b905090565b3360008181526002602090815260408083206001600160a01b0387168085529083529281902085905551848152600193917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a392915050565b6000610ceb60078484612b7a565b9392505050565b333014610d4257604051630330dbc960e11b815260206004820152600560248201527f4e42523a3300000000000000000000000000000000000000000000000000000060448201526064016108ba565b610a9b84848484612c09565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152600090819030906370a0823190602401602060405180830381865afa158015610db0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dd49190613f86565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0387166004820152336024820152909150600090309063dd62ed3e90604401602060405180830381865afa158015610e3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e619190613f86565b90506001600160a01b0386161580610e8057506001600160a01b038516155b15610ece57604051630330dbc960e11b815260206004820152601960248201527f4d617832303a20746f2f66726f6d20616464726573732830290000000000000060448201526064016108ba565b81841115610f1f57604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016108ba565b80841115610f9657604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c7565000000000000000000000000000000000000000000000000000000000060648201526084016108ba565b610fa36001878787612c7a565b9250846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef86604051610fea91815260200190565b60405180910390a361102f86336110018785613fce565b6001600160a01b03928316600090815260026020908152604080832095909416825293909352912055600190565b50336001600160a01b0387167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256110668785613fce565b60405190815260200160405180910390a350509392505050565b7fca4b208a000000000000000000000000000000000000000000000000000000006110ad60078233612b7a565b806110c657506110c660076303e1469160e61b33612b7a565b15611131576110f760077fca4b208b0000000000000000000000000000000000000000000000000000000033612d1d565b611102600733612e47565b61112e60077fca4b208a0000000000000000000000000000000000000000000000000000000033612f5f565b50565b6040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fca4b208a0000000000000000000000000000000000000000000000000000000061119060078233612b7a565b806111a957506111a960076303e1469160e61b33612b7a565b156111315761112e60077fca4b208a0000000000000000000000000000000000000000000000000000000033612f5f565b6001600160a01b037f0000000000000000000000007e51ad847cdf8729efc97cfa6e8afa4d658cb85b1630036112785760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016108ba565b7f0000000000000000000000007e51ad847cdf8729efc97cfa6e8afa4d658cb85b6001600160a01b03166112d37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b03161461134f5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016108ba565b6113588161307e565b6040805160008082526020820190925261112e918391906130e1565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819030906370a0823190602401602060405180830381865afa1580156113cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f19190613f86565b90508083111561144457604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016108ba565b61145060013385613281565b506040518381526001925060009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35b50919050565b816114a160078233612b7a565b806114ba57506114ba60076303e1469160e61b33612b7a565b15611131577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061155057507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b1561157657336001600160a01b038316036111315761157160078484612f5f565b505050565b61157160078484612f5f565b600054610100900460ff16158080156115a25750600054600160ff909116105b806115bc5750303b1580156115bc575060005460ff166001145b61162e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084016108ba565b6000805460ff19166001179055801561166e57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6116e56040518060400160405280600681526020017f78534852415000000000000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f785348524150000000000000000000000000000000000000000000000000000081525060128661331e565b6116ed61344c565b611702600183681b1ae4d6e2ef5000006134cb565b604051681b1ae4d6e2ef50000081526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3801561157157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f0000000000000000000000007e51ad847cdf8729efc97cfa6e8afa4d658cb85b1630036118525760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c000000000000000000000000000000000000000060648201526084016108ba565b7f0000000000000000000000007e51ad847cdf8729efc97cfa6e8afa4d658cb85b6001600160a01b03166118ad7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146119295760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f7879000000000000000000000000000000000000000060648201526084016108ba565b6119328261307e565b61193e828260016130e1565b5050565b6000306001600160a01b037f0000000000000000000000007e51ad847cdf8729efc97cfa6e8afa4d658cb85b16146119e25760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ba565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b7fca4b208b00000000000000000000000000000000000000000000000000000000611a3460078233612b7a565b80611a4d5750611a4d60076303e1469160e61b33612b7a565b156111315761193e60077fca4b208a0000000000000000000000000000000000000000000000000000000084612d1d565b7fca4b208b00000000000000000000000000000000000000000000000000000000611aab60078233612b7a565b80611ac45750611ac460076303e1469160e61b33612b7a565b1561113157611af560077fca4b208b0000000000000000000000000000000000000000000000000000000084612d1d565b611b00600783612e47565b61193e60077fca4b208b0000000000000000000000000000000000000000000000000000000033612f5f565b80611b3960078233612b7a565b80611b525750611b5260076303e1469160e61b33612b7a565b156111315761193e60078333612f5f565b6001600160a01b038116600090815260016020526040812054610c64565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000611bae60078233612b7a565b80611bc75750611bc760076303e1469160e61b33612b7a565b1561113157611bd86007600061355f565b61112e60077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612f5f565b600e6020526000908152604090208054611c1d90613e5d565b80601f0160208091040260200160405190810160405280929190818152602001828054611c4990613e5d565b8015611c965780601f10611c6b57610100808354040283529160200191611c96565b820191906000526020600020905b815481529060010190602001808311611c7957829003601f168201915b505050505081565b7f8da5cb5a00000000000000000000000000000000000000000000000000000000611ccb60078233612b7a565b80611ce45750611ce460076303e1469160e61b33612b7a565b1561113157611d1560077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612d1d565b611d2060073361355f565b61112e60077f8da5cb5a0000000000000000000000000000000000000000000000000000000033612f5f565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152600090819030906370a0823190602401602060405180830381865afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd29190613f86565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0386166004820152336024820152909150600090309063dd62ed3e90604401602060405180830381865afa158015611e3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e5f9190613f86565b90506001600160a01b038516611eb857604051630330dbc960e11b815260206004820152601660248201527f4d617832303a2066726f6d20616464726573732830290000000000000000000060448201526064016108ba565b81841115611f0957604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016108ba565b80841115611f8057604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c7565000000000000000000000000000000000000000000000000000000000060648201526084016108ba565b611f8c60018686613281565b50604051848152600193506000906001600160a01b038716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611fe185336110018785613fce565b50336001600160a01b0386167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256120188785613fce565b60405190815260200160405180910390a3505092915050565b61205d60077fca4b208b0000000000000000000000000000000000000000000000000000000033612b7a565b1561113157600f55565b6060610c7660016135fc565b7f8da5cb5a000000000000000000000000000000000000000000000000000000006120a060078233612b7a565b806120b957506120b960076303e1469160e61b33612b7a565b156111315761112e60077f8da5cb5a0000000000000000000000000000000000000000000000000000000033612f5f565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152336004820152600090819030906370a0823190602401602060405180830381865afa158015612143573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121679190613f86565b90506001600160a01b0384166121c057604051630330dbc960e11b815260206004820152601460248201527f4d617832303a20746f206164647265737328302900000000000000000000000060448201526064016108ba565b8083111561221157604051630330dbc960e11b815260206004820152601a60248201527f4d617832303a206973737566696369656e742062616c616e636500000000000060448201526064016108ba565b61221e6001338686612c7a565b9150836001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161226591815260200190565b60405180910390a35092915050565b7fca4b208b000000000000000000000000000000000000000000000000000000006122a160078233612b7a565b806122ba57506122ba60076303e1469160e61b33612b7a565b15611131576122cb60076000612e47565b61112e60077fca4b208b0000000000000000000000000000000000000000000000000000000033612f5f565b61232360077fca4b208b0000000000000000000000000000000000000000000000000000000033612b7a565b1561113157600c80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f87bf030d6c6aa55db1e81d52f84962fc04ce1d477e64e50d57d3a91c52296f9390600090a250565b33600090815260016020526040902054808211156123d4576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61ffff83166000908152600e6020526040902080546123f290613e5d565b905060000361244457604051630330dbc960e11b815260206004820152601160248201527f546f6b656e3a205452206e6f742073657400000000000000000000000000000060448201526064016108ba565b61245060013384613281565b5060405182815260009033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a360408051336020820152808201849052815180820383018152606082018352600f547e0100000000000000000000000000000000000000000000000000000000000060808401526082808401919091528351808403909101815260a2830193849052600c547f40a7bb100000000000000000000000000000000000000000000000000000000090945290926001926000916001600160a01b0316906340a7bb1090612540908a90309089908790899060a601613fe1565b6040805180830381865afa15801561255c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125809190614033565b509050348111156125d457604051630330dbc960e11b815260206004820152601660248201527f546f6b656e3a206d65737361676520666565206c6f770000000000000000000060448201526064016108ba565b600c5461ffff88166000908152600e602052604080822090517fc58031000000000000000000000000000000000000000000000000000000000081526001600160a01b039093169263c5803100923492612639928d928b913391908b90600401614057565b6000604051808303818588803b15801561265257600080fd5b505af1158015612666573d6000803e3d6000fd5b505050505050505050505050565b61ffff85166000908152600d60205260408082209051612695908790613f6a565b908152604080516020928190038301902067ffffffffffffffff8716600090815292529020600181015490915061270f57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3400000000000000000000000000000000000000000000000000000060448201526064016108ba565b80548214158061273a57508060010154838360405161272f92919061413c565b604051809103902014155b1561278857604051630330dbc960e11b815260206004820152600560248201527f4e42523a3500000000000000000000000000000000000000000000000000000060448201526064016108ba565b600080825560018201556040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a822906127d69089908990899089908990600401614177565b600060405180830381600087803b1580156127f057600080fd5b505af1158015612804573d6000803e3d6000fd5b50505050505050505050565b7f8da5cb5b0000000000000000000000000000000000000000000000000000000061283d60078233612b7a565b80612856575061285660076303e1469160e61b33612b7a565b156111315761193e60077f8da5cb5a0000000000000000000000000000000000000000000000000000000084612d1d565b6001600160a01b038083166000908152600260209081526040808320938516835292905290812054610ceb565b816128c160078233612b7a565b806128da57506128da60076303e1469160e61b33612b7a565b15611131577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061297057507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b156129a7576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61157160078484612d1d565b6129df60077fca4b208b0000000000000000000000000000000000000000000000000000000033612b7a565b156111315761ffff83166000908152600e60205260409020612a02828483614205565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b80567488383836040516117a793929190614302565b7f8da5cb5b00000000000000000000000000000000000000000000000000000000612a6360078233612b7a565b80612a7c5750612a7c60076303e1469160e61b33612b7a565b1561113157612aad60077f8da5cb5b0000000000000000000000000000000000000000000000000000000084612d1d565b612ab860078361355f565b61193e60077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612f5f565b6060816004018054612af590613e5d565b80601f0160208091040260200160405190810160405280929190818152602001828054612b2190613e5d565b8015612b6e5780601f10612b4357610100808354040283529160200191612b6e565b820191906000526020600020905b815481529060010190602001808311612b5157829003601f168201915b50505050509050919050565b60006001600160a01b038216612bbc576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082207fffffffff000000000000000000000000000000000000000000000000000000009390931682529190925290205460ff1690565b60008082806020019051810190612c209190614320565b9092509050612c31600183836134cb565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050505050565b6001600160a01b03831660009081526020859052604081205480831115612ce457604051630330dbc960e11b815260206004820152600760248201527f4d617832303a310000000000000000000000000000000000000000000000000060448201526064016108ba565b50506001600160a01b03808416600090815260208690526040808220805485900390559184168152208054820190556001949350505050565b6001600160a01b038116612d5d576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d68838383612b7a565b15612db657604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a310000000000000000000000000000000000000000000000000060448201526064016108ba565b6001600160a01b0381166000818152602085815260408083207fffffffff00000000000000000000000000000000000000000000000000000000871680855290835292819020805460ff19166001908117909155815193845291830193909352918101919091527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060016117a7565b612e72827fca4b208b0000000000000000000000000000000000000000000000000000000083612b7a565b15612ee4576002820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6001600160a01b038116611131576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b038116612f9f576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612faa838383612b7a565b612ff757604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a320000000000000000000000000000000000000000000000000060448201526064016108ba565b6001600160a01b0381166000818152602085815260408083207fffffffff000000000000000000000000000000000000000000000000000000008716808552908352818420805460ff19169055815190815291820193909352918201527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060016117a7565b6303e1469160e61b61309260078233612b7a565b806130ab57506130ab60076303e1469160e61b33612b7a565b61193e576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615613114576115718361360d565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561316e575060408051601f3d908101601f1916820190925261316b91810190613f86565b60015b6131e05760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f74205555505300000000000000000000000000000000000060648201526084016108ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc81146132755760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c6555554944000000000000000000000000000000000000000000000060648201526084016108ba565b506115718383836136e3565b6001600160a01b038216600090815260208490526040812054808311156132eb57604051630330dbc960e11b815260206004820152600760248201527f4d617832303a310000000000000000000000000000000000000000000000000060448201526064016108ba565b6001600160a01b038416600090815260208690526040902090839003905550600283018054829003905560019392505050565b600054610100900460ff1661339b5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016108ba565b6133a6600185613708565b6133b1600184613716565b6004805460ff191660ff84161790556133d360076303e1469160e61b83612d1d565b6133de600782613724565b61340a60077fca4b208b0000000000000000000000000000000000000000000000000000000083612d1d565b613415600782612e47565b61344160077f8da5cb5b0000000000000000000000000000000000000000000000000000000083612d1d565b610a9b60078261355f565b600054610100900460ff166134c95760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e6700000000000000000000000000000000000000000060648201526084016108ba565b565b6001600160a01b03821661352257604051630330dbc960e11b815260206004820152600760248201527f4d617832303a320000000000000000000000000000000000000000000000000060448201526064016108ba565b80836002016000828254613536919061434e565b90915550506001600160a01b039091166000908152602092909252604090912080549091019055565b61358a827f8da5cb5b0000000000000000000000000000000000000000000000000000000083612b7a565b15612ee4576001820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6060816005018054612af590613e5d565b6001600160a01b0381163b61368a5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e74726163740000000000000000000000000000000000000060648201526084016108ba565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6136ec836137a8565b6000825111806136f95750805b1561157157610a9b83836137e8565b600482016115718282614361565b600582016115718282614361565b613736826303e1469160e61b83612b7a565b15612ee4576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6137b18161360d565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6138675760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e7472616374000000000000000000000000000000000000000000000000000060648201526084016108ba565b600080846001600160a01b0316846040516138829190613f6a565b600060405180830381855af49150503d80600081146138bd576040519150601f19603f3d011682016040523d82523d6000602084013e6138c2565b606091505b50915091506138ea828260405180606001604052806027815260200161445e602791396138f3565b95945050505050565b60608315613902575081610ceb565b8251156139125782518084602001fd5b8160405162461bcd60e51b81526004016108ba9190613b37565b803561ffff8116811461393e57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261398357600080fd5b813567ffffffffffffffff8082111561399e5761399e613943565b604051601f8301601f19908116603f011681019082821181831017156139c6576139c6613943565b816040528381528660208588010111156139df57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff8116811461393e57600080fd5b60008060008060808587031215613a2d57600080fd5b613a368561392c565b9350602085013567ffffffffffffffff80821115613a5357600080fd5b613a5f88838901613972565b9450613a6d604088016139ff565b93506060870135915080821115613a8357600080fd5b50613a9087828801613972565b91505092959194509250565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461393e57600080fd5b600060208284031215613ade57600080fd5b610ceb82613a9c565b60005b83811015613b02578181015183820152602001613aea565b50506000910152565b60008151808452613b23816020860160208601613ae7565b601f01601f19169290920160200192915050565b602081526000610ceb6020830184613b0b565b6001600160a01b038116811461112e57600080fd5b60008060408385031215613b7257600080fd5b8235613b7d81613b4a565b946020939093013593505050565b60008060408385031215613b9e57600080fd5b613ba783613a9c565b91506020830135613bb781613b4a565b809150509250929050565b600080600060608486031215613bd757600080fd5b8335613be281613b4a565b92506020840135613bf281613b4a565b929592945050506040919091013590565b600060208284031215613c1557600080fd5b8135610ceb81613b4a565b600060208284031215613c3257600080fd5b5035919050565b60008060408385031215613c4c57600080fd5b8235613ba781613b4a565b60008060408385031215613c6a57600080fd5b8235613c7581613b4a565b9150602083013567ffffffffffffffff811115613c9157600080fd5b613c9d85828601613972565b9150509250929050565b600060208284031215613cb957600080fd5b610ceb8261392c565b600080600060608486031215613cd757600080fd5b613ce08461392c565b9250602084013567ffffffffffffffff811115613cfc57600080fd5b613d0886828701613972565b925050604084013590509250925092565b60008060408385031215613d2c57600080fd5b613b7d8361392c565b60008083601f840112613d4757600080fd5b50813567ffffffffffffffff811115613d5f57600080fd5b602083019150836020828501011115613d7757600080fd5b9250929050565b600080600080600060808688031215613d9657600080fd5b613d9f8661392c565b9450602086013567ffffffffffffffff80821115613dbc57600080fd5b613dc889838a01613972565b9550613dd6604089016139ff565b94506060880135915080821115613dec57600080fd5b50613df988828901613d35565b969995985093965092949392505050565b600080600060408486031215613e1f57600080fd5b613e288461392c565b9250602084013567ffffffffffffffff811115613e4457600080fd5b613e5086828701613d35565b9497909650939450505050565b600181811c90821680613e7157607f821691505b60208210810361148e577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000808354613eb881613e5d565b60018281168015613ed05760018114613ee557613f14565b60ff1984168752821515830287019450613f14565b8760005260208060002060005b85811015613f0b5781548a820152908401908201613ef2565b50505082870194505b50929695505050505050565b61ffff85168152608060208201526000613f3d6080830186613b0b565b67ffffffffffffffff851660408401528281036060840152613f5f8185613b0b565b979650505050505050565b60008251613f7c818460208701613ae7565b9190910192915050565b600060208284031215613f9857600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115610c6457610c64613f9f565b61ffff861681526001600160a01b038516602082015260a06040820152600061400d60a0830186613b0b565b841515606084015282810360808401526140278185613b0b565b98975050505050505050565b6000806040838503121561404657600080fd5b505080516020909101519092909150565b61ffff871681526000602060c0818401526000885461407581613e5d565b8060c087015260e060018084166000811461409757600181146140b1576140df565b60ff198516838a01528284151560051b8a010195506140df565b8d6000528660002060005b858110156140d75781548b82018601529083019088016140bc565b8a0184019650505b505050505083810360408501526140f68189613b0b565b91505061410e60608401876001600160a01b03169052565b6001600160a01b038516608084015282810360a084015261412f8185613b0b565b9998505050505050505050565b8183823760009101908152919050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b61ffff861681526080602082015260006141946080830187613b0b565b67ffffffffffffffff86166040840152828103606084015261402781858761414c565b601f82111561157157600081815260208120601f850160051c810160208610156141de5750805b601f850160051c820191505b818110156141fd578281556001016141ea565b505050505050565b67ffffffffffffffff83111561421d5761421d613943565b6142318361422b8354613e5d565b836141b7565b6000601f841160018114614283576000851561424d5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556142fb565b600083815260209020601f19861690835b828110156142b45786850135825560209485019460019092019101614294565b50868210156142ef577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff841681526040602082015260006138ea60408301848661414c565b6000806040838503121561433357600080fd5b825161433e81613b4a565b6020939093015192949293505050565b80820180821115610c6457610c64613f9f565b815167ffffffffffffffff81111561437b5761437b613943565b61438f816143898454613e5d565b846141b7565b602080601f8311600181146143e257600084156143ac5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556141fd565b600085815260208120601f198616915b82811015614411578886015182559484019460019091019084016143f2565b508582101561444d57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b75f7f57a16c61f5a05023cfdb3ef1df86b8fe6f3bde5191fd22c41dcebddc4064736f6c63430008130033