Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 14 internal transactions
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 48868381 | 1126 days ago | 0 ETH | ||||
| 48449984 | 1127 days ago | 0 ETH | ||||
| 48445810 | 1127 days ago | 0 ETH | ||||
| 48430331 | 1127 days ago | 0 ETH | ||||
| 48429623 | 1127 days ago | 0 ETH | ||||
| 48429601 | 1127 days ago | 0 ETH | ||||
| 48429584 | 1127 days ago | 0 ETH | ||||
| 48429566 | 1127 days ago | 0 ETH | ||||
| 48429545 | 1127 days ago | 0 ETH | ||||
| 48429522 | 1127 days ago | 0 ETH | ||||
| 48429511 | 1127 days ago | 0 ETH | ||||
| 48429501 | 1127 days ago | 0 ETH | ||||
| 48429491 | 1127 days ago | 0 ETH | ||||
| 48429126 | 1127 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
fBombV2Bridges
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @title: Fantom Bomb, LZ ERC 20 for BOMB/wBOMB on destination chains
* @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
* @notice UUPS 1822 update for Traverse chains.
* @custom:change-log line 3 of traverseChains() if (_amount >= userBal) => if (_amount > userBal)
*/
// 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 "./fAToken-bridges.sol";
import "./lib/Safe20.sol";
import "./lib/20.sol";
contract fBombV2Bridges is fTokenOC {
using Lib20 for Lib20.Token;
using Safe20 for IERC20;
// @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
override {
uint256 userBal = token20.getBalanceOf(msg.sender);
if (_amount > userBal) {
revert Unauthorized();
}
if (trustedRemoteLookup[_chainId].length == 0) {
revert MaxSplaining({
reason: "Token: TR not set"
});
}
// set the amout to burn and send to treasury
uint256 onePer = _amount / 100;
uint256 toTraverse = _amount - (onePer * 2);
// burn FT, eliminating it from circulation on src chain
token20.burn(msg.sender, _amount - onePer);
emit Transfer(msg.sender, address(0), _amount - onePer);
token20.doTransfer(msg.sender, treasury, onePer);
emit Transfer(msg.sender, treasury, onePer);
// abi.encode() the payload with the values to send
bytes memory payload = abi.encode(
msg.sender
, toTraverse);
// 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
);
}
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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;
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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;
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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;
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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;
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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;
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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);
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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"
});
}
}
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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;
}
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @title: [Not an EIP]: Access lists
* @author: @MaxFlowO2 on bird app/GitHub
* @dev Formerly whitelists, now allowlist, or whatever it's called.
* @custom:change-log removed end variable/functions (un-needed)
* @custom:change-log variables renamed from lib whitelist
* @custom:change-log internal -> internal
* @custom:error-code Lists:1 "(user) is already whitelisted."
* @custom:error-code Lists:2 "(user) is not whitelisted."
* @custom:error-code Lists:3 "Whitelist already enabled."
* @custom:error-code Lists:4 "Whitelist already disabled."
* @custom:change-log added custom error codes
* @custom:change-log removed import "./Strings.sol"; (un-needed)
*
* Include with 'using Lists for Lists.Access;'
*/
// 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 "./CountersV2.sol";
library Lists {
using CountersV2 for CountersV2.Counter;
event ListChanged(bool _old, bool _new, address _address);
event ListStatus(bool _old, bool _new);
error MaxSplaining(string reason);
struct Access {
bool _status;
CountersV2.Counter added;
CountersV2.Counter removed;
mapping(address => bool) allowed;
}
function add(
Access storage list
, address user
) internal {
if (list.allowed[user]) {
revert MaxSplaining({
reason : "Lists:1"
});
}
// since now all previous values are false no need for another variable
// and add them to the list!
list.allowed[user] = true;
// increment counter
list.added.increment();
// emit event
emit ListChanged(false, list.allowed[user], user);
}
function remove(
Access storage list
, address user
) internal {
if (!list.allowed[user]) {
revert MaxSplaining({
reason : "Lists:2"
});
}
// since now all previous values are true no need for another variable
// and remove them from the list!
list.allowed[user] = false;
// increment counter
list.removed.increment();
// emit event
emit ListChanged(true, list.allowed[user], user);
}
function enable(
Access storage list
) internal {
if (list._status) {
revert MaxSplaining({
reason : "Lists:3"
});
}
list._status = true;
emit ListStatus(false, list._status);
}
function disable(
Access storage list
) internal {
if (!list._status) {
revert MaxSplaining({
reason : "Lists:4"
});
}
list._status = false;
emit ListStatus(true, list._status);
}
function status(
Access storage list
) internal
view
returns (bool) {
return list._status;
}
function totalAdded(
Access storage list
) internal
view
returns (uint) {
return list.added.current();
}
function totalRemoved(
Access storage list
) internal
view
returns (uint) {
return list.removed.current();
}
function onList(
Access storage list
, address user
) internal
view
returns (bool) {
return list.allowed[user];
}
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @title: CountersV2.sol
* @author Matt Condon (@shrugs)
* @notice Provides counters that can only be incremented, decremented, reset or set.
* This can be used e.g. to track the number of elements in a mapping, issuing ERC721 ids
* or counting request ids.
* @custom:change-log MIT -> Apache-2.0
* @custom:change-log Edited for more NFT functionality added .set(uint)
* @custom:change-log added event CounterNumberChangedTo(uint _number).
* @custom:change-log added error MaxSplaining(string reason).
* @custom:change-log internal -> internal functions
* @custom:error-code CountersV2:1 "No negatives in uints" - overflow protection
*
* Include with `using CountersV2 for CountersV2.Counter;`
*/
// 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 CountersV2 {
struct Counter {
uint256 value;
}
event CounterNumberChangedTo(uint _number);
error MaxSplaining(string reason);
function current(
Counter storage counter
) internal
view
returns (uint256) {
return counter.value;
}
function increment(
Counter storage counter
) internal {
unchecked {
++counter.value;
}
}
function decrement(
Counter storage counter
) internal {
if (counter.value == 0) {
revert MaxSplaining({
reason : "CountersV2:1"
});
}
unchecked {
--counter.value;
}
}
function reset(
Counter storage counter
) internal {
counter.value = 0;
emit CounterNumberChangedTo(counter.value);
}
function set(
Counter storage counter
, uint number
) internal {
counter.value = number;
emit CounterNumberChangedTo(counter.value);
}
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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 {
uint256 accountBal = getBalanceOf(token, account);
if (amount > amount) {
revert MaxSplaining({
reason: "Max20:1"
});
}
unchecked {
token.balances[account] = accountBal - amount;
token.totalSupply -= amount;
}
}
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @title: Fantom Bomb, LZ ERC 20 for BOMB/wBOMB on destination chains
* @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-UUPS-LZ.sol";
import "./lib/Safe20.sol";
import "./lib/20.sol";
import "./lib/Lists.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
contract fTokenOC is Initializable
, Max20ImplementationUUPSLZ
, UUPSUpgradeable {
using Lib20 for Lib20.Token;
using Lists for Lists.Access;
using Safe20 for IERC20;
function disable()
external {
_disableInitializers();
}
function initialize(
string memory _name
, string memory _symbol
, address _admin
, address _dev
, address _owner
) initializer
public {
__Max20_init(_name, _symbol, 18, _admin, _dev, _owner);
__UUPSUpgradeable_init();
}
function _authorizeUpgrade(address newImplementation)
internal
onlyRole(ADMIN)
override
{}
function addExempt(
address newAddress
) external
virtual
onlyDev() {
taxExempt.add(newAddress);
}
function removeExempt(
address newAddress
) external
virtual
onlyDev() {
taxExempt.remove(newAddress);
}
/// @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 (Max20ImplementationUUPSLZ)
returns (bool success) {
if (_to == address(0)) {
revert MaxSplaining({
reason: "Max20: to address(0)"
});
} else {
if (taxExempt.onList(_to) || taxExempt.onList(msg.sender)) {
success = token20.doTransfer(msg.sender, _to, _value);
emit Transfer(msg.sender, _to, _value);
} else {
uint256 transValue = _value * 99 / 100;
success = token20.doTransfer(msg.sender, _to, transValue);
emit Transfer(msg.sender, _to, transValue);
token20.burn(msg.sender, _value - transValue);
emit Transfer(msg.sender, address(0), _value - transValue);
}
}
}
/// @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 (Max20ImplementationUUPSLZ)
returns (bool success) {
uint256 approveBal = this.allowance(_from, msg.sender);
if (_from == address(0) || _to == address(0)) {
revert MaxSplaining({
reason: "Max20: to/from address(0)"
});
} else if (approveBal >= _value) {
revert MaxSplaining({
reason: "Max20: not approved to spend _value"
});
} else {
if (taxExempt.onList(_to) || taxExempt.onList(_from)) {
success = token20.doTransfer(_from, _to, _value);
emit Transfer(_from, _to, _value);
} else {
uint256 transValue = _value * 99 / 100;
success = token20.doTransfer(_from, _to, transValue);
emit Transfer(_from, _to, transValue);
token20.burn(_from, _value - transValue);
emit Transfer(_from, address(0), _value - transValue);
}
}
}
function setTres(
address newAddress
) external
virtual
onlyDev() {
treasury = newAddress;
}
// @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"
});
}
// set the amout to burn and send to treasury
uint256 onePer = _amount / 100;
uint256 toTraverse = _amount - (onePer * 2);
// burn FT, eliminating it from circulation on src chain
token20.burn(msg.sender, _amount - onePer);
emit Transfer(msg.sender, address(0), _amount - onePer);
token20.doTransfer(msg.sender, treasury, onePer);
emit Transfer(msg.sender, treasury, onePer);
// abi.encode() the payload with the values to send
bytes memory payload = abi.encode(
msg.sender
, toTraverse);
// 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;
}
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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
);
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @title: EIP-20: Token Standard, extension
* @author: Unknown
* @notice: n/a
* @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 IERC20Burn is IERC165 {
/// @dev to burn ERC20 tokens
/// @param amount uint256 amount of tokens to burn
function burn(
uint256 amount
) external;
function deposit(uint256 amount) external returns (bool);
function withdraw(uint256 amount) external returns (bool);
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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);
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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;
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @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);
}/* +%%#- ##. =+. .+#%#+: *%%#: .**+- =+
* .%@@*#*: @@: *%- #%*= .*@@=. =%. .%@@*%* +@@=+=% .%##
* .%@@- -=+ *@% :@@- #@=# -@@* +@- :@@@: ==* -%%. *** #@=*
* %@@: -.* :. +@@-.#@# =@%#. :. -@* :@@@. -:# .%. *@# *@#*
* *%@- +++ +@#.-- .*%*. .#@@*@# %@@%*#@@: .@@=-. -%- #%@: +*- =*@* -@%=:
* @@% =## +@@#-..%%:%.-@@=-@@+ .. +@% #@#*+@: .*= @@% =#* -*. +#. %@#+*@
* @@# +@* #@# +@@. -+@@+#*@% =#: #@= :@@-.%# -=. : @@# .*@* =@= :*@:=@@-:@+
* -#%+@#- :@#@@+%++@*@*:=%+..%%#= *@ *@++##. =%@%@%%#- =#%+@#- :*+**+=: %%++%*
*
* @title Max-20-UUPS-LZ-Implementation
* @author Max Flow O2 -> @MaxFlowO2 on bird app/GitHub
* @dev
*/
// 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/IERC20Burn.sol";
import "./lib/Safe20.sol";
import "./lib/20.sol";
import "./modules/access/MaxAccess.sol";
import "./lib/Roles.sol";
import "./lib/Lists.sol";
import "./lz/ILayerZeroReceiver.sol";
import "./lz/ILayerZeroEndpoint.sol";
import "./errors/MaxErrors.sol";
abstract contract Max20ImplementationUUPSLZ is Initializable
, MaxErrors
, MaxAccess
, ILayerZeroReceiver
, IERC20 {
//////////////////////////////////////
// Storage
//////////////////////////////////////
using Lib20 for Lib20.Token;
using Lists for Lists.Access;
using Roles for Roles.Role;
using Safe20 for IERC20;
Lib20.Token internal token20;
Roles.Role internal contractRoles;
Lists.Access internal taxExempt;
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;
address internal Token;
address internal WToken;
address internal treasury;
//////////////////////////////////////
// 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
, address _dev
, address _owner
) internal
onlyInitializing() {
token20.setName(_name);
token20.setSymbol(_symbol);
token20.setDecimals(_decimals);
contractRoles.add(ADMIN, _admin);
contractRoles.setAdmin(_admin);
contractRoles.add(DEVS, _dev);
contractRoles.setDeveloper(_dev);
contractRoles.add(OWNERS, _owner);
contractRoles.setOwner(_owner);
}
//////////////////////////
// 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) {
if (_to == address(0)) {
revert MaxSplaining({
reason: "Max20: to address(0)"
});
} 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 approveBal = this.allowance(_from, msg.sender);
if (_from == address(0) || _to == address(0)) {
revert MaxSplaining({
reason: "Max20: to/from address(0)"
});
} else if (approveBal >= _value) {
revert MaxSplaining({
reason: "Max20: not approved to spend _value"
});
} else {
success = token20.doTransfer(_from, _to, _value);
emit Transfer(_from, _to, _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) {
return token20.getAllowance(_owner, _spender);
}
///////////////////
/// 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(IERC20).interfaceId
);
}
uint256[35] private __gap;
}// 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
}
}
}// 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);
}
}
}
}// 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;
}// 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);
}
}
}// 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);
}// 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;
}// 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);
}{
"remappings": [],
"optimizer": {
"enabled": true,
"runs": 10000
},
"evmVersion": "london",
"libraries": {},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"string","name":"reason","type":"string"}],"name":"MaxSplaining","type":"error"},{"inputs":[{"internalType":"uint256","name":"yourTime","type":"uint256"},{"internalType":"uint256","name":"hitTime","type":"uint256"}],"name":"TooLateBoomer","type":"error"},{"inputs":[{"internalType":"uint256","name":"yourTime","type":"uint256"},{"internalType":"uint256","name":"hitTime","type":"uint256"}],"name":"TooSoonJunior","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_endpoint","type":"address"}],"name":"EndpointSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_chainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_trustedRemote","type":"bytes"}],"name":"TrustedRemoteSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"acceptDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"addExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"remaining","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentLZGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"declineDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"declineOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"developer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"failedMessages","outputs":[{"internalType":"uint256","name":"payloadLength","type":"uint256"},{"internalType":"bytes32","name":"payloadHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"address","name":"_dev","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"onLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newDeveloper","type":"address"}],"name":"pushDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"pushOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"removeExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"role","type":"bytes4"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newEndpoint","type":"address"}],"name":"setEndPoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newVal","type":"uint256"}],"name":"setGasForDestinationLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"}],"name":"setTres","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"bytes","name":"_trustedRemote","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDeveloper","type":"address"}],"name":"transferDeveloper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"traverseChains","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
60a06040523060805234801561001457600080fd5b5060805161434961004c600039600081816111dc0152818161127201528181611464015281816114fa01526115f501526143496000f3fe6080604052600436106102f15760003560e01c806370a082311161018f578063ad6d9c17116100e1578063d39ce77c1161008a578063de02cde711610064578063de02cde71461084e578063eb8d72b71461086e578063f2fde38b1461088e57600080fd5b8063d39ce77c146107ee578063db0ed6a01461080e578063dd62ed3e1461082e57600080fd5b8063cb40cb49116100bb578063cb40cb49146107a8578063cf89fa03146107c8578063d1deba1f146107db57600080fd5b8063ad6d9c1714610755578063b24ac7b71461076a578063ca4b208b1461078a57600080fd5b80638da5cb5b1161014357806395d89b411161011d57806395d89b411461070b578063a86ff96014610720578063a9059cbb1461073557600080fd5b80638da5cb5b1461064e5780638ee7491214610680578063943fb872146106eb57600080fd5b80637533d788116101745780637533d788146105f95780637835137a1461061957806379ba50971461063957600080fd5b806370a08231146105c4578063715018a6146105e457600080fd5b8063313ce567116102485780634f1ef286116101fc5780636149d871116101d65780636149d8711461056457806364cb4edb1461058457806366278a6c146105a457600080fd5b80634f1ef286146104e457806352d1902d146104f75780635ba5e9f01461050c57600080fd5b80633659cfe61161022d5780633659cfe61461048f57806344faded0146104af578063475de12e146104cf57600080fd5b8063313ce5671461045857806331e26cfd1461047a57600080fd5b806318160ddd116102aa57806323b872dd1161028457806323b872dd1461040e5780632bfcf0f21461042e5780632f2770db1461044357600080fd5b806318160ddd146103af5780631c37a822146103ce5780631cdd35c9146103ee57600080fd5b806306fdde03116102db57806306fdde031461034d578063095ea7b31461036f57806310ab94321461038f57600080fd5b80621d3567146102f657806301ffc9a714610318575b600080fd5b34801561030257600080fd5b506103166103113660046137b8565b6108ae565b005b34801561032457600080fd5b5061033861033336600461386d565b610aec565b60405190151581526020015b60405180910390f35b34801561035957600080fd5b50610362610c69565b60405161034491906138d8565b34801561037b57600080fd5b5061033861038a366004613900565b610c7a565b34801561039b57600080fd5b506103386103aa36600461392c565b610cdc565b3480156103bb57600080fd5b506003545b604051908152602001610344565b3480156103da57600080fd5b506103166103e93660046137b8565b610cf1565b3480156103fa57600080fd5b50610316610409366004613963565b610d4d565b34801561041a57600080fd5b50610338610429366004613980565b610da5565b34801561043a57600080fd5b506103166110bc565b34801561044f57600080fd5b50610316611151565b34801561046457600080fd5b5060045460405160ff9091168152602001610344565b34801561048657600080fd5b5061031661115b565b34801561049b57600080fd5b506103166104aa366004613963565b6111d2565b3480156104bb57600080fd5b506103166104ca36600461392c565b61136c565b3480156104db57600080fd5b506015546103c0565b6103166104f23660046139c1565b61145a565b34801561050357600080fd5b506103c06115e8565b34801561051857600080fd5b5061053361052736600461386d565b506303e1469160e61b90565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610344565b34801561057057600080fd5b5061031661057f366004613963565b6116ad565b34801561059057600080fd5b5061031661059f366004613963565b61170b565b3480156105b057600080fd5b506103166105bf36600461386d565b61176e565b3480156105d057600080fd5b506103c06105df366004613963565b6117a5565b3480156105f057600080fd5b506103166117c3565b34801561060557600080fd5b50610362610614366004613a11565b611846565b34801561062557600080fd5b50610316610634366004613963565b6118e0565b34801561064557600080fd5b50610316611930565b34801561065a57600080fd5b506008546001600160a01b03165b6040516001600160a01b039091168152602001610344565b34801561068c57600080fd5b506106d661069b366004613a2c565b601360209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b60408051928352602083019190915201610344565b3480156106f757600080fd5b50610316610706366004613a83565b6119de565b34801561071757600080fd5b506103626119fb565b34801561072c57600080fd5b50610316611a07565b34801561074157600080fd5b50610338610750366004613900565b611a7e565b34801561076157600080fd5b50610316611c3e565b34801561077657600080fd5b50610316610785366004613963565b611c8f565b34801561079657600080fd5b506009546001600160a01b0316610668565b3480156107b457600080fd5b506103166107c3366004613963565b611cb2565b6103166107d6366004613a9c565b611d2c565b6103166107e9366004613b01565b6120a8565b3480156107fa57600080fd5b50610316610809366004613963565b612244565b34801561081a57600080fd5b50610316610829366004613b8d565b6122bb565b34801561083a57600080fd5b506103c0610849366004613c2b565b612429565b34801561085a57600080fd5b5061031661086936600461392c565b612456565b34801561087a57600080fd5b50610316610889366004613c49565b612555565b34801561089a57600080fd5b506103166108a9366004613963565b6125cc565b6012546001600160a01b0316331461090e57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3100000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61ffff84166000908152601460205260409020805461092c90613c9c565b9050835114158061096c575061ffff84166000908152601460205260409081902090516109599190613cef565b6040518091039020838051906020012014155b156109ba57604051630330dbc960e11b815260206004820152600560248201527f4e42523a320000000000000000000000000000000000000000000000000000006044820152606401610905565b6040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a822906109fc908790879087908790600401613d65565b600060405180830381600087803b158015610a1657600080fd5b505af1925050508015610a27575060015b610ae6576040518060400160405280825181526020018280519060200120815250601360008661ffff1661ffff16815260200190815260200160002084604051610a719190613daf565b90815260408051918290036020908101832067ffffffffffffffff8716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d90610add908690869086908690613d65565b60405180910390a15b50505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7f5828d0000000000000000000000000000000000000000000000000000000001480610b7f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f7319562d00000000000000000000000000000000000000000000000000000000145b80610bcb57507fffffffff0000000000000000000000000000000000000000000000000000000082167f78bab63900000000000000000000000000000000000000000000000000000000145b80610c1757507fffffffff0000000000000000000000000000000000000000000000000000000082167fb7d1e49900000000000000000000000000000000000000000000000000000000145b80610c6357507fffffffff0000000000000000000000000000000000000000000000000000000082167f942e8b2200000000000000000000000000000000000000000000000000000000145b92915050565b6060610c75600161267a565b905090565b3360008181526002602090815260408083206001600160a01b0387168085529083529281902085905551848152600193917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a392915050565b6000610cea60078484612710565b9392505050565b333014610d4157604051630330dbc960e11b815260206004820152600560248201527f4e42523a330000000000000000000000000000000000000000000000000000006044820152606401610905565b610ae68484848461279f565b610d60600763ca4b208b60e01b33612710565b15610d7357610d70600b82612810565b50565b6040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201523360248201526000908190309063dd62ed3e90604401602060405180830381865afa158015610e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190613dcb565b90506001600160a01b0385161580610e5057506001600160a01b038416155b15610e9e57604051630330dbc960e11b815260206004820152601960248201527f4d617832303a20746f2f66726f6d2061646472657373283029000000000000006044820152606401610905565b828110610f1457604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c756500000000000000000000000000000000000000000000000000000000006064820152608401610905565b6001600160a01b0384166000908152600e602052604090205460ff1680610f5357506001600160a01b0385166000908152600e602052604090205460ff165b15610fb957610f65600186868661291a565b9150836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610fac91815260200190565b60405180910390a36110b4565b60006064610fc8856063613e13565b610fd29190613e2a565b9050610fe1600187878461291a565b9250846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161102891815260200190565b60405180910390a361106a8661103e8387613e65565b6001600160a01b0390911660009081526001602052604090208054829003905560038054919091039055565b60006001600160a01b0387167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6110a18488613e65565b60405190815260200160405180910390a3505b509392505050565b7fca4b208a000000000000000000000000000000000000000000000000000000006110e960078233612710565b80611102575061110260076303e1469160e61b33612710565b15610d735761111a600763ca4b208b60e01b336129bd565b611125600733612ae7565b610d7060077fca4b208a0000000000000000000000000000000000000000000000000000000033612be6565b611159612d05565b565b7fca4b208a0000000000000000000000000000000000000000000000000000000061118860078233612710565b806111a157506111a160076303e1469160e61b33612710565b15610d7357610d7060077fca4b208a0000000000000000000000000000000000000000000000000000000033612be6565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036112705760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610905565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166112cb7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146113475760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610905565b61135081612dd6565b60408051600080825260208201909252610d7091839190612e39565b8161137960078233612710565b80611392575061139260076303e1469160e61b33612710565b15610d73577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061142857507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b1561144e57336001600160a01b03831603610d735761144960078484612be6565b505050565b61144960078484612be6565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036114f85760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610905565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166115537f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146115cf5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610905565b6115d882612dd6565b6115e482826001612e39565b5050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146116885760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610905565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b63ca4b208b60e01b6116c160078233612710565b806116da57506116da60076303e1469160e61b33612710565b15610d73576115e460077fca4b208a00000000000000000000000000000000000000000000000000000000846129bd565b63ca4b208b60e01b61171f60078233612710565b80611738575061173860076303e1469160e61b33612710565b15610d7357611750600763ca4b208b60e01b846129bd565b61175b600783612ae7565b6115e4600763ca4b208b60e01b33612be6565b8061177b60078233612710565b80611794575061179460076303e1469160e61b33612710565b15610d73576115e460078333612be6565b6001600160a01b038116600090815260016020526040812054610c63565b7f8da5cb5b000000000000000000000000000000000000000000000000000000006117f060078233612710565b80611809575061180960076303e1469160e61b33612710565b15610d735761181a60076000612fd9565b610d7060077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612be6565b6014602052600090815260409020805461185f90613c9c565b80601f016020809104026020016040519081016040528092919081815260200182805461188b90613c9c565b80156118d85780601f106118ad576101008083540402835291602001916118d8565b820191906000526020600020905b8154815290600101906020018083116118bb57829003601f168201915b505050505081565b6118f3600763ca4b208b60e01b33612710565b15610d7357601180546001600160a01b0383167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905550565b7f8da5cb5a0000000000000000000000000000000000000000000000000000000061195d60078233612710565b80611976575061197660076303e1469160e61b33612710565b15610d73576119a760077f8da5cb5b00000000000000000000000000000000000000000000000000000000336129bd565b6119b2600733612fd9565b610d7060077f8da5cb5a0000000000000000000000000000000000000000000000000000000033612be6565b6119f1600763ca4b208b60e01b33612710565b15610d7357601555565b6060610c756001613076565b7f8da5cb5a00000000000000000000000000000000000000000000000000000000611a3460078233612710565b80611a4d5750611a4d60076303e1469160e61b33612710565b15610d7357610d7060077f8da5cb5a0000000000000000000000000000000000000000000000000000000033612be6565b60006001600160a01b038316611ad757604051630330dbc960e11b815260206004820152601460248201527f4d617832303a20746f20616464726573732830290000000000000000000000006044820152606401610905565b6001600160a01b0383166000908152600e602052604090205460ff1680611b0d5750336000908152600e602052604090205460ff165b15611b7357611b1f600133858561291a565b9050826001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611b6691815260200190565b60405180910390a3610c63565b60006064611b82846063613e13565b611b8c9190613e2a565b9050611b9b600133868461291a565b9150836001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611be291815260200190565b60405180910390a3611bf83361103e8386613e65565b6000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef611c268487613e65565b60405190815260200160405180910390a35092915050565b63ca4b208b60e01b611c5260078233612710565b80611c6b5750611c6b60076303e1469160e61b33612710565b15610d7357611c7c60076000612ae7565b610d70600763ca4b208b60e01b33612be6565b611ca2600763ca4b208b60e01b33612710565b15610d7357610d70600b82613087565b611cc5600763ca4b208b60e01b33612710565b15610d7357601280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f87bf030d6c6aa55db1e81d52f84962fc04ce1d477e64e50d57d3a91c52296f9390600090a250565b3360009081526001602052604090205480821115611d76576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61ffff831660009081526014602052604090208054611d9490613c9c565b9050600003611de657604051630330dbc960e11b815260206004820152601160248201527f546f6b656e3a205452206e6f74207365740000000000000000000000000000006044820152606401610905565b6000611df3606484613e2a565b90506000611e02826002613e13565b611e0c9085613e65565b9050611e1c3361103e8487613e65565b6000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef611e4a8588613e65565b60405190815260200160405180910390a3601154611e769060019033906001600160a01b03168561291a565b506011546040518381526001600160a01b039091169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3604080513360208201528082018390528151808203830181526060820183526015547e0100000000000000000000000000000000000000000000000000000000000060808401526082808401919091528351808403909101815260a28301938490526012547f40a7bb100000000000000000000000000000000000000000000000000000000090945290926001926000916001600160a01b0316906340a7bb1090611f72908c90309089908790899060a601613e78565b6040805180830381865afa158015611f8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb29190613eca565b5090503481111561200657604051630330dbc960e11b815260206004820152601660248201527f546f6b656e3a206d65737361676520666565206c6f77000000000000000000006044820152606401610905565b60125461ffff8a1660009081526014602052604080822090517fc58031000000000000000000000000000000000000000000000000000000000081526001600160a01b039093169263c580310092349261206b928f928b913391908b90600401613eee565b6000604051808303818588803b15801561208457600080fd5b505af1158015612098573d6000803e3d6000fd5b5050505050505050505050505050565b61ffff851660009081526013602052604080822090516120c9908790613daf565b908152604080516020928190038301902067ffffffffffffffff8716600090815292529020600181015490915061214357604051630330dbc960e11b815260206004820152600560248201527f4e42523a340000000000000000000000000000000000000000000000000000006044820152606401610905565b80548214158061216e575080600101548383604051612163929190613fd3565b604051809103902014155b156121bc57604051630330dbc960e11b815260206004820152600560248201527f4e42523a350000000000000000000000000000000000000000000000000000006044820152606401610905565b600080825560018201556040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a8229061220a908990899089908990899060040161400e565b600060405180830381600087803b15801561222457600080fd5b505af1158015612238573d6000803e3d6000fd5b50505050505050505050565b7f8da5cb5b0000000000000000000000000000000000000000000000000000000061227160078233612710565b8061228a575061228a60076303e1469160e61b33612710565b15610d73576115e460077f8da5cb5a00000000000000000000000000000000000000000000000000000000846129bd565b600054610100900460ff16158080156122db5750600054600160ff909116105b806122f55750303b1580156122f5575060005460ff166001145b6123675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610905565b6000805460ff1916600117905580156123a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6123b686866012878787613188565b6123be61329d565b801561242157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6001600160a01b038083166000908152600260209081526040808320938516835292905290812054610cea565b8161246360078233612710565b8061247c575061247c60076303e1469160e61b33612710565b15610d73577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061251257507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b15612549576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611449600784846129bd565b612568600763ca4b208b60e01b33612710565b15610d735761ffff8316600090815260146020526040902061258b828483614094565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b80567488383836040516125bf93929190614191565b60405180910390a1505050565b7f8da5cb5b000000000000000000000000000000000000000000000000000000006125f960078233612710565b80612612575061261260076303e1469160e61b33612710565b15610d735761264360077f8da5cb5b00000000000000000000000000000000000000000000000000000000846129bd565b61264e600783612fd9565b6115e460077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612be6565b606081600401805461268b90613c9c565b80601f01602080910402602001604051908101604052809291908181526020018280546126b790613c9c565b80156127045780601f106126d957610100808354040283529160200191612704565b820191906000526020600020905b8154815290600101906020018083116126e757829003601f168201915b50505050509050919050565b60006001600160a01b038216612752576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082207fffffffff000000000000000000000000000000000000000000000000000000009390931682529190925290205460ff1690565b600080828060200190518101906127b691906141af565b90925090506127c76001838361331a565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050505050565b6001600160a01b038116600090815260038301602052604090205460ff161561287c57604051630330dbc960e11b815260206004820152600760248201527f4c697374733a31000000000000000000000000000000000000000000000000006044820152606401610905565b6001600160a01b03811660009081526003830160205260409020805460ff191660019081179091556128b390830180546001019055565b6001600160a01b0381166000818152600384016020908152604080832054815193845260ff161515918301919091528101919091527f42fa9f1391f36d7a12900fccb1e67467edf81e7f3771d34cbd23a4fe01f473e0906060015b60405180910390a15050565b6001600160a01b0383166000908152602085905260408120548083111561298457604051630330dbc960e11b815260206004820152600760248201527f4d617832303a31000000000000000000000000000000000000000000000000006044820152606401610905565b50506001600160a01b03808416600090815260208690526040808220805485900390559184168152208054820190556001949350505050565b6001600160a01b0381166129fd576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a08838383612710565b15612a5657604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a31000000000000000000000000000000000000000000000000006044820152606401610905565b6001600160a01b0381166000818152602085815260408083207fffffffff00000000000000000000000000000000000000000000000000000000871680855290835292819020805460ff19166001908117909155815193845291830193909352918101919091527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060016125bf565b612af98263ca4b208b60e01b83612710565b15612b6b576002820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6001600160a01b038116610d73576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b038116612c26576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c31838383612710565b612c7e57604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a32000000000000000000000000000000000000000000000000006044820152606401610905565b6001600160a01b0381166000818152602085815260408083207fffffffff000000000000000000000000000000000000000000000000000000008716808552908352818420805460ff19169055815190815291820193909352918201527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060016125bf565b600054610100900460ff1615612d835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960448201527f616c697a696e67000000000000000000000000000000000000000000000000006064820152608401610905565b60005460ff9081161015611159576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1565b6303e1469160e61b612dea60078233612710565b80612e035750612e0360076303e1469160e61b33612710565b6115e4576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612e6c57611449836133ae565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612ec6575060408051601f3d908101601f19168201909252612ec391810190613dcb565b60015b612f385760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608401610905565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114612fcd5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152608401610905565b50611449838383613484565b613004827f8da5cb5b0000000000000000000000000000000000000000000000000000000083612710565b15612b6b576001820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b606081600501805461268b90613c9c565b6001600160a01b038116600090815260038301602052604090205460ff166130f257604051630330dbc960e11b815260206004820152600760248201527f4c697374733a32000000000000000000000000000000000000000000000000006044820152606401610905565b6001600160a01b03811660009081526003830160205260409020805460ff191690556131246002830180546001019055565b6001600160a01b03811660008181526003840160209081526040918290205482516001815260ff909116151591810191909152908101919091527f42fa9f1391f36d7a12900fccb1e67467edf81e7f3771d34cbd23a4fe01f473e09060600161290e565b600054610100900460ff166132055760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610905565b6132106001876134a9565b61321b6001866134b7565b6004805460ff191660ff861617905561323d60076303e1469160e61b856129bd565b6132486007846134c5565b61325b600763ca4b208b60e01b846129bd565b613266600783612ae7565b61329260077f8da5cb5b00000000000000000000000000000000000000000000000000000000836129bd565b612421600782612fd9565b600054610100900460ff166111595760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610905565b6001600160a01b03821661337157604051630330dbc960e11b815260206004820152600760248201527f4d617832303a32000000000000000000000000000000000000000000000000006044820152606401610905565b8083600201600082825461338591906141dd565b90915550506001600160a01b039091166000908152602092909252604090912080549091019055565b6001600160a01b0381163b61342b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610905565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b61348d83613549565b60008251118061349a5750805b1561144957610ae68383613589565b6004820161144982826141f0565b6005820161144982826141f0565b6134d7826303e1469160e61b83612710565b15612b6b576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b613552816133ae565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6136085760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610905565b600080846001600160a01b0316846040516136239190613daf565b600060405180830381855af49150503d806000811461365e576040519150601f19603f3d011682016040523d82523d6000602084013e613663565b606091505b509150915061368b82826040518060600160405280602781526020016142ed60279139613694565b95945050505050565b606083156136a3575081610cea565b8251156136b35782518084602001fd5b8160405162461bcd60e51b815260040161090591906138d8565b803561ffff811681146136df57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261372457600080fd5b813567ffffffffffffffff8082111561373f5761373f6136e4565b604051601f8301601f19908116603f01168101908282118183101715613767576137676136e4565b8160405283815286602085880101111561378057600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff811681146136df57600080fd5b600080600080608085870312156137ce57600080fd5b6137d7856136cd565b9350602085013567ffffffffffffffff808211156137f457600080fd5b61380088838901613713565b945061380e604088016137a0565b9350606087013591508082111561382457600080fd5b5061383187828801613713565b91505092959194509250565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146136df57600080fd5b60006020828403121561387f57600080fd5b610cea8261383d565b60005b838110156138a357818101518382015260200161388b565b50506000910152565b600081518084526138c4816020860160208601613888565b601f01601f19169290920160200192915050565b602081526000610cea60208301846138ac565b6001600160a01b0381168114610d7057600080fd5b6000806040838503121561391357600080fd5b823561391e816138eb565b946020939093013593505050565b6000806040838503121561393f57600080fd5b6139488361383d565b91506020830135613958816138eb565b809150509250929050565b60006020828403121561397557600080fd5b8135610cea816138eb565b60008060006060848603121561399557600080fd5b83356139a0816138eb565b925060208401356139b0816138eb565b929592945050506040919091013590565b600080604083850312156139d457600080fd5b82356139df816138eb565b9150602083013567ffffffffffffffff8111156139fb57600080fd5b613a0785828601613713565b9150509250929050565b600060208284031215613a2357600080fd5b610cea826136cd565b600080600060608486031215613a4157600080fd5b613a4a846136cd565b9250602084013567ffffffffffffffff811115613a6657600080fd5b613a7286828701613713565b925050604084013590509250925092565b600060208284031215613a9557600080fd5b5035919050565b60008060408385031215613aaf57600080fd5b61391e836136cd565b60008083601f840112613aca57600080fd5b50813567ffffffffffffffff811115613ae257600080fd5b602083019150836020828501011115613afa57600080fd5b9250929050565b600080600080600060808688031215613b1957600080fd5b613b22866136cd565b9450602086013567ffffffffffffffff80821115613b3f57600080fd5b613b4b89838a01613713565b9550613b59604089016137a0565b94506060880135915080821115613b6f57600080fd5b50613b7c88828901613ab8565b969995985093965092949392505050565b600080600080600060a08688031215613ba557600080fd5b853567ffffffffffffffff80821115613bbd57600080fd5b613bc989838a01613713565b96506020880135915080821115613bdf57600080fd5b50613bec88828901613713565b9450506040860135613bfd816138eb565b92506060860135613c0d816138eb565b91506080860135613c1d816138eb565b809150509295509295909350565b60008060408385031215613c3e57600080fd5b8235613948816138eb565b600080600060408486031215613c5e57600080fd5b613c67846136cd565b9250602084013567ffffffffffffffff811115613c8357600080fd5b613c8f86828701613ab8565b9497909650939450505050565b600181811c90821680613cb057607f821691505b602082108103613ce9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000808354613cfd81613c9c565b60018281168015613d155760018114613d2a57613d59565b60ff1984168752821515830287019450613d59565b8760005260208060002060005b85811015613d505781548a820152908401908201613d37565b50505082870194505b50929695505050505050565b61ffff85168152608060208201526000613d8260808301866138ac565b67ffffffffffffffff851660408401528281036060840152613da481856138ac565b979650505050505050565b60008251613dc1818460208701613888565b9190910192915050565b600060208284031215613ddd57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610c6357610c63613de4565b600082613e60577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b81810381811115610c6357610c63613de4565b61ffff861681526001600160a01b038516602082015260a060408201526000613ea460a08301866138ac565b84151560608401528281036080840152613ebe81856138ac565b98975050505050505050565b60008060408385031215613edd57600080fd5b505080516020909101519092909150565b61ffff871681526000602060c08184015260008854613f0c81613c9c565b8060c087015260e0600180841660008114613f2e5760018114613f4857613f76565b60ff198516838a01528284151560051b8a01019550613f76565b8d6000528660002060005b85811015613f6e5781548b8201860152908301908801613f53565b8a0184019650505b50505050508381036040850152613f8d81896138ac565b915050613fa560608401876001600160a01b03169052565b6001600160a01b038516608084015282810360a0840152613fc681856138ac565b9998505050505050505050565b8183823760009101908152919050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b61ffff8616815260806020820152600061402b60808301876138ac565b67ffffffffffffffff861660408401528281036060840152613ebe818587613fe3565b601f82111561144957600081815260208120601f850160051c810160208610156140755750805b601f850160051c820191505b8181101561242157828155600101614081565b67ffffffffffffffff8311156140ac576140ac6136e4565b6140c0836140ba8354613c9c565b8361404e565b6000601f84116001811461411257600085156140dc5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561418a565b600083815260209020601f19861690835b828110156141435786850135825560209485019460019092019101614123565b508682101561417e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff8416815260406020820152600061368b604083018486613fe3565b600080604083850312156141c257600080fd5b82516141cd816138eb565b6020939093015192949293505050565b80820180821115610c6357610c63613de4565b815167ffffffffffffffff81111561420a5761420a6136e4565b61421e816142188454613c9c565b8461404e565b602080601f831160018114614271576000841561423b5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612421565b600085815260208120601f198616915b828110156142a057888601518255948401946001909101908401614281565b50858210156142dc57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212202e474433d3aaff80c4cef14cf72490796dd6503ec500e1289dec11b0cbd11e7a64736f6c63430008110033
Deployed Bytecode
0x6080604052600436106102f15760003560e01c806370a082311161018f578063ad6d9c17116100e1578063d39ce77c1161008a578063de02cde711610064578063de02cde71461084e578063eb8d72b71461086e578063f2fde38b1461088e57600080fd5b8063d39ce77c146107ee578063db0ed6a01461080e578063dd62ed3e1461082e57600080fd5b8063cb40cb49116100bb578063cb40cb49146107a8578063cf89fa03146107c8578063d1deba1f146107db57600080fd5b8063ad6d9c1714610755578063b24ac7b71461076a578063ca4b208b1461078a57600080fd5b80638da5cb5b1161014357806395d89b411161011d57806395d89b411461070b578063a86ff96014610720578063a9059cbb1461073557600080fd5b80638da5cb5b1461064e5780638ee7491214610680578063943fb872146106eb57600080fd5b80637533d788116101745780637533d788146105f95780637835137a1461061957806379ba50971461063957600080fd5b806370a08231146105c4578063715018a6146105e457600080fd5b8063313ce567116102485780634f1ef286116101fc5780636149d871116101d65780636149d8711461056457806364cb4edb1461058457806366278a6c146105a457600080fd5b80634f1ef286146104e457806352d1902d146104f75780635ba5e9f01461050c57600080fd5b80633659cfe61161022d5780633659cfe61461048f57806344faded0146104af578063475de12e146104cf57600080fd5b8063313ce5671461045857806331e26cfd1461047a57600080fd5b806318160ddd116102aa57806323b872dd1161028457806323b872dd1461040e5780632bfcf0f21461042e5780632f2770db1461044357600080fd5b806318160ddd146103af5780631c37a822146103ce5780631cdd35c9146103ee57600080fd5b806306fdde03116102db57806306fdde031461034d578063095ea7b31461036f57806310ab94321461038f57600080fd5b80621d3567146102f657806301ffc9a714610318575b600080fd5b34801561030257600080fd5b506103166103113660046137b8565b6108ae565b005b34801561032457600080fd5b5061033861033336600461386d565b610aec565b60405190151581526020015b60405180910390f35b34801561035957600080fd5b50610362610c69565b60405161034491906138d8565b34801561037b57600080fd5b5061033861038a366004613900565b610c7a565b34801561039b57600080fd5b506103386103aa36600461392c565b610cdc565b3480156103bb57600080fd5b506003545b604051908152602001610344565b3480156103da57600080fd5b506103166103e93660046137b8565b610cf1565b3480156103fa57600080fd5b50610316610409366004613963565b610d4d565b34801561041a57600080fd5b50610338610429366004613980565b610da5565b34801561043a57600080fd5b506103166110bc565b34801561044f57600080fd5b50610316611151565b34801561046457600080fd5b5060045460405160ff9091168152602001610344565b34801561048657600080fd5b5061031661115b565b34801561049b57600080fd5b506103166104aa366004613963565b6111d2565b3480156104bb57600080fd5b506103166104ca36600461392c565b61136c565b3480156104db57600080fd5b506015546103c0565b6103166104f23660046139c1565b61145a565b34801561050357600080fd5b506103c06115e8565b34801561051857600080fd5b5061053361052736600461386d565b506303e1469160e61b90565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610344565b34801561057057600080fd5b5061031661057f366004613963565b6116ad565b34801561059057600080fd5b5061031661059f366004613963565b61170b565b3480156105b057600080fd5b506103166105bf36600461386d565b61176e565b3480156105d057600080fd5b506103c06105df366004613963565b6117a5565b3480156105f057600080fd5b506103166117c3565b34801561060557600080fd5b50610362610614366004613a11565b611846565b34801561062557600080fd5b50610316610634366004613963565b6118e0565b34801561064557600080fd5b50610316611930565b34801561065a57600080fd5b506008546001600160a01b03165b6040516001600160a01b039091168152602001610344565b34801561068c57600080fd5b506106d661069b366004613a2c565b601360209081526000938452604080852084518086018401805192815290840195840195909520945292905282529020805460019091015482565b60408051928352602083019190915201610344565b3480156106f757600080fd5b50610316610706366004613a83565b6119de565b34801561071757600080fd5b506103626119fb565b34801561072c57600080fd5b50610316611a07565b34801561074157600080fd5b50610338610750366004613900565b611a7e565b34801561076157600080fd5b50610316611c3e565b34801561077657600080fd5b50610316610785366004613963565b611c8f565b34801561079657600080fd5b506009546001600160a01b0316610668565b3480156107b457600080fd5b506103166107c3366004613963565b611cb2565b6103166107d6366004613a9c565b611d2c565b6103166107e9366004613b01565b6120a8565b3480156107fa57600080fd5b50610316610809366004613963565b612244565b34801561081a57600080fd5b50610316610829366004613b8d565b6122bb565b34801561083a57600080fd5b506103c0610849366004613c2b565b612429565b34801561085a57600080fd5b5061031661086936600461392c565b612456565b34801561087a57600080fd5b50610316610889366004613c49565b612555565b34801561089a57600080fd5b506103166108a9366004613963565b6125cc565b6012546001600160a01b0316331461090e57604051630330dbc960e11b815260206004820152600560248201527f4e42523a3100000000000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b61ffff84166000908152601460205260409020805461092c90613c9c565b9050835114158061096c575061ffff84166000908152601460205260409081902090516109599190613cef565b6040518091039020838051906020012014155b156109ba57604051630330dbc960e11b815260206004820152600560248201527f4e42523a320000000000000000000000000000000000000000000000000000006044820152606401610905565b6040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a822906109fc908790879087908790600401613d65565b600060405180830381600087803b158015610a1657600080fd5b505af1925050508015610a27575060015b610ae6576040518060400160405280825181526020018280519060200120815250601360008661ffff1661ffff16815260200190815260200160002084604051610a719190613daf565b90815260408051918290036020908101832067ffffffffffffffff8716600090815290825291909120835181559201516001909201919091557fe6f254030bcb01ffd20558175c13fcaed6d1520be7becee4c961b65f79243b0d90610add908690869086908690613d65565b60405180910390a15b50505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7f5828d0000000000000000000000000000000000000000000000000000000001480610b7f57507fffffffff0000000000000000000000000000000000000000000000000000000082167f7319562d00000000000000000000000000000000000000000000000000000000145b80610bcb57507fffffffff0000000000000000000000000000000000000000000000000000000082167f78bab63900000000000000000000000000000000000000000000000000000000145b80610c1757507fffffffff0000000000000000000000000000000000000000000000000000000082167fb7d1e49900000000000000000000000000000000000000000000000000000000145b80610c6357507fffffffff0000000000000000000000000000000000000000000000000000000082167f942e8b2200000000000000000000000000000000000000000000000000000000145b92915050565b6060610c75600161267a565b905090565b3360008181526002602090815260408083206001600160a01b0387168085529083529281902085905551848152600193917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a392915050565b6000610cea60078484612710565b9392505050565b333014610d4157604051630330dbc960e11b815260206004820152600560248201527f4e42523a330000000000000000000000000000000000000000000000000000006044820152606401610905565b610ae68484848461279f565b610d60600763ca4b208b60e01b33612710565b15610d7357610d70600b82612810565b50565b6040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201523360248201526000908190309063dd62ed3e90604401602060405180830381865afa158015610e0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e319190613dcb565b90506001600160a01b0385161580610e5057506001600160a01b038416155b15610e9e57604051630330dbc960e11b815260206004820152601960248201527f4d617832303a20746f2f66726f6d2061646472657373283029000000000000006044820152606401610905565b828110610f1457604051630330dbc960e11b815260206004820152602360248201527f4d617832303a206e6f7420617070726f76656420746f207370656e64205f766160448201527f6c756500000000000000000000000000000000000000000000000000000000006064820152608401610905565b6001600160a01b0384166000908152600e602052604090205460ff1680610f5357506001600160a01b0385166000908152600e602052604090205460ff165b15610fb957610f65600186868661291a565b9150836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610fac91815260200190565b60405180910390a36110b4565b60006064610fc8856063613e13565b610fd29190613e2a565b9050610fe1600187878461291a565b9250846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161102891815260200190565b60405180910390a361106a8661103e8387613e65565b6001600160a01b0390911660009081526001602052604090208054829003905560038054919091039055565b60006001600160a01b0387167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef6110a18488613e65565b60405190815260200160405180910390a3505b509392505050565b7fca4b208a000000000000000000000000000000000000000000000000000000006110e960078233612710565b80611102575061110260076303e1469160e61b33612710565b15610d735761111a600763ca4b208b60e01b336129bd565b611125600733612ae7565b610d7060077fca4b208a0000000000000000000000000000000000000000000000000000000033612be6565b611159612d05565b565b7fca4b208a0000000000000000000000000000000000000000000000000000000061118860078233612710565b806111a157506111a160076303e1469160e61b33612710565b15610d7357610d7060077fca4b208a0000000000000000000000000000000000000000000000000000000033612be6565b6001600160a01b037f0000000000000000000000005c09a9ce08c4b332ef1cc5f7cadb1158c32767ce1630036112705760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610905565b7f0000000000000000000000005c09a9ce08c4b332ef1cc5f7cadb1158c32767ce6001600160a01b03166112cb7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146113475760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610905565b61135081612dd6565b60408051600080825260208201909252610d7091839190612e39565b8161137960078233612710565b80611392575061139260076303e1469160e61b33612710565b15610d73577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061142857507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b1561144e57336001600160a01b03831603610d735761144960078484612be6565b505050565b61144960078484612be6565b6001600160a01b037f0000000000000000000000005c09a9ce08c4b332ef1cc5f7cadb1158c32767ce1630036114f85760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f64656c656761746563616c6c00000000000000000000000000000000000000006064820152608401610905565b7f0000000000000000000000005c09a9ce08c4b332ef1cc5f7cadb1158c32767ce6001600160a01b03166115537f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b0316146115cf5760405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201527f6163746976652070726f787900000000000000000000000000000000000000006064820152608401610905565b6115d882612dd6565b6115e482826001612e39565b5050565b6000306001600160a01b037f0000000000000000000000005c09a9ce08c4b332ef1cc5f7cadb1158c32767ce16146116885760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610905565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b63ca4b208b60e01b6116c160078233612710565b806116da57506116da60076303e1469160e61b33612710565b15610d73576115e460077fca4b208a00000000000000000000000000000000000000000000000000000000846129bd565b63ca4b208b60e01b61171f60078233612710565b80611738575061173860076303e1469160e61b33612710565b15610d7357611750600763ca4b208b60e01b846129bd565b61175b600783612ae7565b6115e4600763ca4b208b60e01b33612be6565b8061177b60078233612710565b80611794575061179460076303e1469160e61b33612710565b15610d73576115e460078333612be6565b6001600160a01b038116600090815260016020526040812054610c63565b7f8da5cb5b000000000000000000000000000000000000000000000000000000006117f060078233612710565b80611809575061180960076303e1469160e61b33612710565b15610d735761181a60076000612fd9565b610d7060077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612be6565b6014602052600090815260409020805461185f90613c9c565b80601f016020809104026020016040519081016040528092919081815260200182805461188b90613c9c565b80156118d85780601f106118ad576101008083540402835291602001916118d8565b820191906000526020600020905b8154815290600101906020018083116118bb57829003601f168201915b505050505081565b6118f3600763ca4b208b60e01b33612710565b15610d7357601180546001600160a01b0383167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617905550565b7f8da5cb5a0000000000000000000000000000000000000000000000000000000061195d60078233612710565b80611976575061197660076303e1469160e61b33612710565b15610d73576119a760077f8da5cb5b00000000000000000000000000000000000000000000000000000000336129bd565b6119b2600733612fd9565b610d7060077f8da5cb5a0000000000000000000000000000000000000000000000000000000033612be6565b6119f1600763ca4b208b60e01b33612710565b15610d7357601555565b6060610c756001613076565b7f8da5cb5a00000000000000000000000000000000000000000000000000000000611a3460078233612710565b80611a4d5750611a4d60076303e1469160e61b33612710565b15610d7357610d7060077f8da5cb5a0000000000000000000000000000000000000000000000000000000033612be6565b60006001600160a01b038316611ad757604051630330dbc960e11b815260206004820152601460248201527f4d617832303a20746f20616464726573732830290000000000000000000000006044820152606401610905565b6001600160a01b0383166000908152600e602052604090205460ff1680611b0d5750336000908152600e602052604090205460ff165b15611b7357611b1f600133858561291a565b9050826001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611b6691815260200190565b60405180910390a3610c63565b60006064611b82846063613e13565b611b8c9190613e2a565b9050611b9b600133868461291a565b9150836001600160a01b0316336001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611be291815260200190565b60405180910390a3611bf83361103e8386613e65565b6000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef611c268487613e65565b60405190815260200160405180910390a35092915050565b63ca4b208b60e01b611c5260078233612710565b80611c6b5750611c6b60076303e1469160e61b33612710565b15610d7357611c7c60076000612ae7565b610d70600763ca4b208b60e01b33612be6565b611ca2600763ca4b208b60e01b33612710565b15610d7357610d70600b82613087565b611cc5600763ca4b208b60e01b33612710565b15610d7357601280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f87bf030d6c6aa55db1e81d52f84962fc04ce1d477e64e50d57d3a91c52296f9390600090a250565b3360009081526001602052604090205480821115611d76576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61ffff831660009081526014602052604090208054611d9490613c9c565b9050600003611de657604051630330dbc960e11b815260206004820152601160248201527f546f6b656e3a205452206e6f74207365740000000000000000000000000000006044820152606401610905565b6000611df3606484613e2a565b90506000611e02826002613e13565b611e0c9085613e65565b9050611e1c3361103e8487613e65565b6000337fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef611e4a8588613e65565b60405190815260200160405180910390a3601154611e769060019033906001600160a01b03168561291a565b506011546040518381526001600160a01b039091169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3604080513360208201528082018390528151808203830181526060820183526015547e0100000000000000000000000000000000000000000000000000000000000060808401526082808401919091528351808403909101815260a28301938490526012547f40a7bb100000000000000000000000000000000000000000000000000000000090945290926001926000916001600160a01b0316906340a7bb1090611f72908c90309089908790899060a601613e78565b6040805180830381865afa158015611f8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611fb29190613eca565b5090503481111561200657604051630330dbc960e11b815260206004820152601660248201527f546f6b656e3a206d65737361676520666565206c6f77000000000000000000006044820152606401610905565b60125461ffff8a1660009081526014602052604080822090517fc58031000000000000000000000000000000000000000000000000000000000081526001600160a01b039093169263c580310092349261206b928f928b913391908b90600401613eee565b6000604051808303818588803b15801561208457600080fd5b505af1158015612098573d6000803e3d6000fd5b5050505050505050505050505050565b61ffff851660009081526013602052604080822090516120c9908790613daf565b908152604080516020928190038301902067ffffffffffffffff8716600090815292529020600181015490915061214357604051630330dbc960e11b815260206004820152600560248201527f4e42523a340000000000000000000000000000000000000000000000000000006044820152606401610905565b80548214158061216e575080600101548383604051612163929190613fd3565b604051809103902014155b156121bc57604051630330dbc960e11b815260206004820152600560248201527f4e42523a350000000000000000000000000000000000000000000000000000006044820152606401610905565b600080825560018201556040517f1c37a8220000000000000000000000000000000000000000000000000000000081523090631c37a8229061220a908990899089908990899060040161400e565b600060405180830381600087803b15801561222457600080fd5b505af1158015612238573d6000803e3d6000fd5b50505050505050505050565b7f8da5cb5b0000000000000000000000000000000000000000000000000000000061227160078233612710565b8061228a575061228a60076303e1469160e61b33612710565b15610d73576115e460077f8da5cb5a00000000000000000000000000000000000000000000000000000000846129bd565b600054610100900460ff16158080156122db5750600054600160ff909116105b806122f55750303b1580156122f5575060005460ff166001145b6123675760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610905565b6000805460ff1916600117905580156123a757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6123b686866012878787613188565b6123be61329d565b801561242157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b6001600160a01b038083166000908152600260209081526040808320938516835292905290812054610cea565b8161246360078233612710565b8061247c575061247c60076303e1469160e61b33612710565b15610d73577fffffffff0000000000000000000000000000000000000000000000000000000083167fca4b208a00000000000000000000000000000000000000000000000000000000148061251257507fffffffff0000000000000000000000000000000000000000000000000000000083167f8da5cb5a00000000000000000000000000000000000000000000000000000000145b15612549576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611449600784846129bd565b612568600763ca4b208b60e01b33612710565b15610d735761ffff8316600090815260146020526040902061258b828483614094565b507f93c35c217d799290d33244ef8905b63167d13758ab18343cd8055ed1b80567488383836040516125bf93929190614191565b60405180910390a1505050565b7f8da5cb5b000000000000000000000000000000000000000000000000000000006125f960078233612710565b80612612575061261260076303e1469160e61b33612710565b15610d735761264360077f8da5cb5b00000000000000000000000000000000000000000000000000000000846129bd565b61264e600783612fd9565b6115e460077f8da5cb5b0000000000000000000000000000000000000000000000000000000033612be6565b606081600401805461268b90613c9c565b80601f01602080910402602001604051908101604052809291908181526020018280546126b790613c9c565b80156127045780601f106126d957610100808354040283529160200191612704565b820191906000526020600020905b8154815290600101906020018083116126e757829003601f168201915b50505050509050919050565b60006001600160a01b038216612752576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b03166000908152602092835260408082207fffffffff000000000000000000000000000000000000000000000000000000009390931682529190925290205460ff1690565b600080828060200190518101906127b691906141af565b90925090506127c76001838361331a565b6040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050505050565b6001600160a01b038116600090815260038301602052604090205460ff161561287c57604051630330dbc960e11b815260206004820152600760248201527f4c697374733a31000000000000000000000000000000000000000000000000006044820152606401610905565b6001600160a01b03811660009081526003830160205260409020805460ff191660019081179091556128b390830180546001019055565b6001600160a01b0381166000818152600384016020908152604080832054815193845260ff161515918301919091528101919091527f42fa9f1391f36d7a12900fccb1e67467edf81e7f3771d34cbd23a4fe01f473e0906060015b60405180910390a15050565b6001600160a01b0383166000908152602085905260408120548083111561298457604051630330dbc960e11b815260206004820152600760248201527f4d617832303a31000000000000000000000000000000000000000000000000006044820152606401610905565b50506001600160a01b03808416600090815260208690526040808220805485900390559184168152208054820190556001949350505050565b6001600160a01b0381166129fd576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612a08838383612710565b15612a5657604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a31000000000000000000000000000000000000000000000000006044820152606401610905565b6001600160a01b0381166000818152602085815260408083207fffffffff00000000000000000000000000000000000000000000000000000000871680855290835292819020805460ff19166001908117909155815193845291830193909352918101919091527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060016125bf565b612af98263ca4b208b60e01b83612710565b15612b6b576002820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f2cfca82ac51c2fc6b6db547820d28d526a505e12d230afb8bf112a5aeefa9a4c90600090a3505050565b6001600160a01b038116610d73576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b6001600160a01b038116612c26576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612c31838383612710565b612c7e57604051630330dbc960e11b815260206004820152600760248201527f526f6c65733a32000000000000000000000000000000000000000000000000006044820152606401610905565b6001600160a01b0381166000818152602085815260408083207fffffffff000000000000000000000000000000000000000000000000000000008716808552908352818420805460ff19169055815190815291820193909352918201527fc8bed56f8e046b5a3f2c2b2be85045ea5c972dc18ad669157957897b4d26e9f7906060016125bf565b600054610100900460ff1615612d835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e69746960448201527f616c697a696e67000000000000000000000000000000000000000000000000006064820152608401610905565b60005460ff9081161015611159576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a1565b6303e1469160e61b612dea60078233612710565b80612e035750612e0360076303e1469160e61b33612710565b6115e4576040517f82b4290000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612e6c57611449836133ae565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612ec6575060408051601f3d908101601f19168201909252612ec391810190613dcb565b60015b612f385760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201527f6f6e206973206e6f7420555550530000000000000000000000000000000000006064820152608401610905565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114612fcd5760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f7860448201527f6961626c655555494400000000000000000000000000000000000000000000006064820152608401610905565b50611449838383613484565b613004827f8da5cb5b0000000000000000000000000000000000000000000000000000000083612710565b15612b6b576001820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b606081600501805461268b90613c9c565b6001600160a01b038116600090815260038301602052604090205460ff166130f257604051630330dbc960e11b815260206004820152600760248201527f4c697374733a32000000000000000000000000000000000000000000000000006044820152606401610905565b6001600160a01b03811660009081526003830160205260409020805460ff191690556131246002830180546001019055565b6001600160a01b03811660008181526003840160209081526040918290205482516001815260ff909116151591810191909152908101919091527f42fa9f1391f36d7a12900fccb1e67467edf81e7f3771d34cbd23a4fe01f473e09060600161290e565b600054610100900460ff166132055760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610905565b6132106001876134a9565b61321b6001866134b7565b6004805460ff191660ff861617905561323d60076303e1469160e61b856129bd565b6132486007846134c5565b61325b600763ca4b208b60e01b846129bd565b613266600783612ae7565b61329260077f8da5cb5b00000000000000000000000000000000000000000000000000000000836129bd565b612421600782612fd9565b600054610100900460ff166111595760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e670000000000000000000000000000000000000000006064820152608401610905565b6001600160a01b03821661337157604051630330dbc960e11b815260206004820152600760248201527f4d617832303a32000000000000000000000000000000000000000000000000006044820152606401610905565b8083600201600082825461338591906141dd565b90915550506001600160a01b039091166000908152602092909252604090912080549091019055565b6001600160a01b0381163b61342b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e7472616374000000000000000000000000000000000000006064820152608401610905565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b61348d83613549565b60008251118061349a5750805b1561144957610ae68383613589565b6004820161144982826141f0565b6005820161144982826141f0565b6134d7826303e1469160e61b83612710565b15612b6b576003820180546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907ff8ccb027dfcd135e000e9d45e6cc2d662578a8825d4c45b5e32e0adf67e79ec690600090a3505050565b613552816133ae565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6136085760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f60448201527f6e747261637400000000000000000000000000000000000000000000000000006064820152608401610905565b600080846001600160a01b0316846040516136239190613daf565b600060405180830381855af49150503d806000811461365e576040519150601f19603f3d011682016040523d82523d6000602084013e613663565b606091505b509150915061368b82826040518060600160405280602781526020016142ed60279139613694565b95945050505050565b606083156136a3575081610cea565b8251156136b35782518084602001fd5b8160405162461bcd60e51b815260040161090591906138d8565b803561ffff811681146136df57600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261372457600080fd5b813567ffffffffffffffff8082111561373f5761373f6136e4565b604051601f8301601f19908116603f01168101908282118183101715613767576137676136e4565b8160405283815286602085880101111561378057600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff811681146136df57600080fd5b600080600080608085870312156137ce57600080fd5b6137d7856136cd565b9350602085013567ffffffffffffffff808211156137f457600080fd5b61380088838901613713565b945061380e604088016137a0565b9350606087013591508082111561382457600080fd5b5061383187828801613713565b91505092959194509250565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146136df57600080fd5b60006020828403121561387f57600080fd5b610cea8261383d565b60005b838110156138a357818101518382015260200161388b565b50506000910152565b600081518084526138c4816020860160208601613888565b601f01601f19169290920160200192915050565b602081526000610cea60208301846138ac565b6001600160a01b0381168114610d7057600080fd5b6000806040838503121561391357600080fd5b823561391e816138eb565b946020939093013593505050565b6000806040838503121561393f57600080fd5b6139488361383d565b91506020830135613958816138eb565b809150509250929050565b60006020828403121561397557600080fd5b8135610cea816138eb565b60008060006060848603121561399557600080fd5b83356139a0816138eb565b925060208401356139b0816138eb565b929592945050506040919091013590565b600080604083850312156139d457600080fd5b82356139df816138eb565b9150602083013567ffffffffffffffff8111156139fb57600080fd5b613a0785828601613713565b9150509250929050565b600060208284031215613a2357600080fd5b610cea826136cd565b600080600060608486031215613a4157600080fd5b613a4a846136cd565b9250602084013567ffffffffffffffff811115613a6657600080fd5b613a7286828701613713565b925050604084013590509250925092565b600060208284031215613a9557600080fd5b5035919050565b60008060408385031215613aaf57600080fd5b61391e836136cd565b60008083601f840112613aca57600080fd5b50813567ffffffffffffffff811115613ae257600080fd5b602083019150836020828501011115613afa57600080fd5b9250929050565b600080600080600060808688031215613b1957600080fd5b613b22866136cd565b9450602086013567ffffffffffffffff80821115613b3f57600080fd5b613b4b89838a01613713565b9550613b59604089016137a0565b94506060880135915080821115613b6f57600080fd5b50613b7c88828901613ab8565b969995985093965092949392505050565b600080600080600060a08688031215613ba557600080fd5b853567ffffffffffffffff80821115613bbd57600080fd5b613bc989838a01613713565b96506020880135915080821115613bdf57600080fd5b50613bec88828901613713565b9450506040860135613bfd816138eb565b92506060860135613c0d816138eb565b91506080860135613c1d816138eb565b809150509295509295909350565b60008060408385031215613c3e57600080fd5b8235613948816138eb565b600080600060408486031215613c5e57600080fd5b613c67846136cd565b9250602084013567ffffffffffffffff811115613c8357600080fd5b613c8f86828701613ab8565b9497909650939450505050565b600181811c90821680613cb057607f821691505b602082108103613ce9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b6000808354613cfd81613c9c565b60018281168015613d155760018114613d2a57613d59565b60ff1984168752821515830287019450613d59565b8760005260208060002060005b85811015613d505781548a820152908401908201613d37565b50505082870194505b50929695505050505050565b61ffff85168152608060208201526000613d8260808301866138ac565b67ffffffffffffffff851660408401528281036060840152613da481856138ac565b979650505050505050565b60008251613dc1818460208701613888565b9190910192915050565b600060208284031215613ddd57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417610c6357610c63613de4565b600082613e60577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b81810381811115610c6357610c63613de4565b61ffff861681526001600160a01b038516602082015260a060408201526000613ea460a08301866138ac565b84151560608401528281036080840152613ebe81856138ac565b98975050505050505050565b60008060408385031215613edd57600080fd5b505080516020909101519092909150565b61ffff871681526000602060c08184015260008854613f0c81613c9c565b8060c087015260e0600180841660008114613f2e5760018114613f4857613f76565b60ff198516838a01528284151560051b8a01019550613f76565b8d6000528660002060005b85811015613f6e5781548b8201860152908301908801613f53565b8a0184019650505b50505050508381036040850152613f8d81896138ac565b915050613fa560608401876001600160a01b03169052565b6001600160a01b038516608084015282810360a0840152613fc681856138ac565b9998505050505050505050565b8183823760009101908152919050565b818352818160208501375060006020828401015260006020601f19601f840116840101905092915050565b61ffff8616815260806020820152600061402b60808301876138ac565b67ffffffffffffffff861660408401528281036060840152613ebe818587613fe3565b601f82111561144957600081815260208120601f850160051c810160208610156140755750805b601f850160051c820191505b8181101561242157828155600101614081565b67ffffffffffffffff8311156140ac576140ac6136e4565b6140c0836140ba8354613c9c565b8361404e565b6000601f84116001811461411257600085156140dc5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561418a565b600083815260209020601f19861690835b828110156141435786850135825560209485019460019092019101614123565b508682101561417e577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff8416815260406020820152600061368b604083018486613fe3565b600080604083850312156141c257600080fd5b82516141cd816138eb565b6020939093015192949293505050565b80820180821115610c6357610c63613de4565b815167ffffffffffffffff81111561420a5761420a6136e4565b61421e816142188454613c9c565b8461404e565b602080601f831160018114614271576000841561423b5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555612421565b600085815260208120601f198616915b828110156142a057888601518255948401946001909101908401614281565b50858210156142dc57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b0190555056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212202e474433d3aaff80c4cef14cf72490796dd6503ec500e1289dec11b0cbd11e7a64736f6c63430008110033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.