Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 610 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap And Bridge | 20418464 | 180 days ago | IN | 0 ETH | 0.00137682 | ||||
Swap And Bridge | 20415612 | 181 days ago | IN | 0.0006 ETH | 0.00041515 | ||||
Swap And Call | 20394400 | 184 days ago | IN | 0.00000277 ETH | 0.00045691 | ||||
Swap And Call | 20391897 | 184 days ago | IN | 0.00000277 ETH | 0.00089839 | ||||
Swap And Call | 20388005 | 184 days ago | IN | 0.07500277 ETH | 0.00185332 | ||||
Swap And Call | 20386241 | 185 days ago | IN | 0.00000277 ETH | 0.00140694 | ||||
Swap And Call | 20385855 | 185 days ago | IN | 0.00000277 ETH | 0.00104771 | ||||
Swap And Call | 20385771 | 185 days ago | IN | 0.00000277 ETH | 0.00113228 | ||||
Swap And Call | 20385677 | 185 days ago | IN | 0.00000277 ETH | 0.00135514 | ||||
Swap And Call | 20384720 | 185 days ago | IN | 0.00000277 ETH | 0.00158797 | ||||
Swap And Call | 20384699 | 185 days ago | IN | 0.00000277 ETH | 0.0018029 | ||||
Swap And Call | 20384459 | 185 days ago | IN | 0.00000277 ETH | 0.00327821 | ||||
Swap And Bridge | 20382250 | 185 days ago | IN | 0.05 ETH | 0.00117686 | ||||
Swap And Bridge | 20378761 | 186 days ago | IN | 0 ETH | 0.00251313 | ||||
Swap And Bridge | 20378756 | 186 days ago | IN | 0 ETH | 0.00356379 | ||||
Swap And Bridge | 20378748 | 186 days ago | IN | 0 ETH | 0.00568141 | ||||
Swap And Bridge | 20378730 | 186 days ago | IN | 0 ETH | 0.00244918 | ||||
Swap And Bridge | 20378705 | 186 days ago | IN | 0 ETH | 0.00302142 | ||||
Swap And Call | 20376374 | 186 days ago | IN | 0.00000277 ETH | 0.00092253 | ||||
Swap And Call | 20374293 | 186 days ago | IN | 0.00000277 ETH | 0.00072691 | ||||
Swap And Call | 20373554 | 186 days ago | IN | 0.00000277 ETH | 0.00065882 | ||||
Swap And Call | 20373137 | 186 days ago | IN | 0.00000277 ETH | 0.00065548 | ||||
Swap And Call | 20373127 | 186 days ago | IN | 0.00000277 ETH | 0.00059864 | ||||
Swap And Call | 20373092 | 186 days ago | IN | 0.00000277 ETH | 0.00069633 | ||||
Swap And Call | 20373091 | 186 days ago | IN | 0.00000277 ETH | 0.00069925 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
20418885 | 180 days ago | 4.98 ETH | ||||
20418885 | 180 days ago | 4.98 ETH | ||||
20418822 | 180 days ago | 0.36 ETH | ||||
20418822 | 180 days ago | 0.36 ETH | ||||
20417976 | 180 days ago | 0.44 ETH | ||||
20417976 | 180 days ago | 0.44 ETH | ||||
20417820 | 180 days ago | 0.74098369 ETH | ||||
20417820 | 180 days ago | 0.74098369 ETH | ||||
20417683 | 180 days ago | 0.2428 ETH | ||||
20417683 | 180 days ago | 0.2428 ETH | ||||
20416535 | 180 days ago | 0.4 ETH | ||||
20416535 | 180 days ago | 0.4 ETH | ||||
20416446 | 180 days ago | 2.005 ETH | ||||
20416446 | 180 days ago | 2.005 ETH | ||||
20415925 | 181 days ago | 1.5 ETH | ||||
20415925 | 181 days ago | 1.5 ETH | ||||
20415843 | 181 days ago | 0.1 ETH | ||||
20415843 | 181 days ago | 0.1 ETH | ||||
20415668 | 181 days ago | 0.001 ETH | ||||
20415668 | 181 days ago | 0.001 ETH | ||||
20415612 | 181 days ago | 0.0006 ETH | ||||
20412731 | 181 days ago | 0.082 ETH | ||||
20412731 | 181 days ago | 0.082 ETH | ||||
20412100 | 181 days ago | 0.36945818 ETH | ||||
20412100 | 181 days ago | 0.36945818 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
ButterRouterV2
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.21; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@butternetwork/bridge/contracts/interface/IButterMosV2.sol"; import "@butternetwork/bridge/contracts/interface/IButterReceiver.sol"; import "./lib/ErrorMessage.sol"; import "./abstract/Router.sol"; import "./lib/Helper.sol"; contract ButterRouterV2 is Router, ReentrancyGuard, IButterReceiver { using SafeERC20 for IERC20; using Address for address; address public mosAddress; uint256 public gasForReFund = 80000; struct BridgeParam { uint256 toChain; bytes receiver; bytes data; } event SetMos(address indexed mos); event SetGasForReFund(uint256 indexed _gasForReFund); event SwapAndBridge( bytes32 indexed orderId, address indexed from, address indexed originToken, address bridgeToken, uint256 originAmount, uint256 bridgeAmount, uint256 fromChain, uint256 toChain, bytes to ); event RemoteSwapAndCall( bytes32 indexed orderId, address indexed receiver, address indexed target, address originToken, address swapToken, uint256 originAmount, uint256 swapAmount, uint256 callAmount, uint256 fromChain, uint256 toChain, bytes from ); constructor(address _mosAddress, address _owner, address _wToken) payable Router(_owner, _wToken) { _setMosAddress(_mosAddress); } function swapAndBridge( address _srcToken, uint256 _amount, bytes calldata _swapData, bytes calldata _bridgeData, bytes calldata _permitData ) external payable nonReentrant transferIn(_srcToken, _amount, _permitData) { require(_swapData.length + _bridgeData.length > 0, ErrorMessage.DATA_EMPTY); SwapTemp memory swapTemp; swapTemp.srcToken = _srcToken; swapTemp.srcAmount = _amount; swapTemp.swapToken = _srcToken; swapTemp.swapAmount = _amount; bytes memory receiver; if (_swapData.length > 0) { Helper.SwapParam memory swap = abi.decode(_swapData, (Helper.SwapParam)); bool result; (result, swapTemp.swapToken, swapTemp.swapAmount) = _makeSwap(swapTemp.srcAmount, swapTemp.srcToken, swap); require(result, ErrorMessage.SWAP_FAIL); require(swapTemp.swapAmount >= swap.minReturnAmount, ErrorMessage.RECEIVE_LOW); if (_bridgeData.length == 0 && swapTemp.swapAmount > 0) { receiver = abi.encodePacked(swap.receiver); Helper._transfer(swapTemp.swapToken, swap.receiver, swapTemp.swapAmount); } } bytes32 orderId; if (_bridgeData.length > 0) { BridgeParam memory bridge = abi.decode(_bridgeData, (BridgeParam)); swapTemp.toChain = bridge.toChain; receiver = bridge.receiver; orderId = _doBridge(msg.sender, swapTemp.swapToken, swapTemp.swapAmount, bridge); } emit SwapAndBridge( orderId, msg.sender, swapTemp.srcToken, swapTemp.swapToken, swapTemp.srcAmount, swapTemp.swapAmount, block.chainid, swapTemp.toChain, receiver ); } function swapAndCall( bytes32 _transferId, address _srcToken, uint256 _amount, FeeType _feeType, bytes calldata _swapData, bytes calldata _callbackData, bytes calldata _permitData ) external payable nonReentrant transferIn(_srcToken, _amount, _permitData) { SwapTemp memory swapTemp; swapTemp.srcToken = _srcToken; swapTemp.srcAmount = _amount; swapTemp.transferId = _transferId; swapTemp.feeType = _feeType; require(_swapData.length + _callbackData.length > 0, ErrorMessage.DATA_EMPTY); (, swapTemp.swapAmount) = _collectFee( swapTemp.srcToken, swapTemp.srcAmount, swapTemp.transferId, swapTemp.feeType ); ( swapTemp.receiver, swapTemp.target, swapTemp.swapToken, swapTemp.swapAmount, swapTemp.callAmount ) = _doSwapAndCall(_swapData, _callbackData, swapTemp.srcToken, swapTemp.swapAmount); if (swapTemp.swapAmount > swapTemp.callAmount) { Helper._transfer(swapTemp.swapToken, swapTemp.receiver, (swapTemp.swapAmount - swapTemp.callAmount)); } emit SwapAndCall( msg.sender, swapTemp.receiver, swapTemp.target, swapTemp.transferId, swapTemp.srcToken, swapTemp.swapToken, swapTemp.srcAmount, swapTemp.swapAmount, swapTemp.callAmount ); } // _srcToken must erc20 Token or wToken function onReceived( bytes32 _orderId, address _srcToken, uint256 _amount, uint256 _fromChain, bytes calldata _from, bytes calldata _swapAndCall ) external nonReentrant { SwapTemp memory swapTemp; swapTemp.srcToken = _srcToken; swapTemp.srcAmount = _amount; swapTemp.swapToken = _srcToken; swapTemp.swapAmount = _amount; swapTemp.fromChain = _fromChain; swapTemp.toChain = block.chainid; swapTemp.from = _from; nativeBalanceBeforeExec = address(this).balance; require(msg.sender == mosAddress, ErrorMessage.MOS_ONLY); require(Helper._getBalance(swapTemp.srcToken, address(this)) >= _amount, ErrorMessage.RECEIVE_LOW); (bytes memory _swapData, bytes memory _callbackData) = abi.decode(_swapAndCall, (bytes, bytes)); require(_swapData.length + _callbackData.length > 0, ErrorMessage.DATA_EMPTY); bool result = true; uint256 minExecGas = gasForReFund * 2; if (_swapData.length > 0) { Helper.SwapParam memory swap = abi.decode(_swapData, (Helper.SwapParam)); swapTemp.receiver = swap.receiver; if (gasleft() > minExecGas) { try this.doRemoteSwap{gas: gasleft() - gasForReFund}(swap, swapTemp.srcToken, swapTemp.srcAmount) returns (address target, address dstToken, uint256 dstAmount) { swapTemp.swapToken = dstToken; swapTemp.target = target; swapTemp.swapAmount = dstAmount; } catch { result = false; } } } if (_callbackData.length > 0) { Helper.CallbackParam memory callParam = abi.decode(_callbackData, (Helper.CallbackParam)); if (swapTemp.receiver == address(0)) { swapTemp.receiver = callParam.receiver; } if (result && gasleft() > minExecGas) { try this.doRemoteCall{gas: gasleft() - gasForReFund}(callParam, swapTemp.swapToken, swapTemp.swapAmount) returns (address target, uint256 callAmount) { swapTemp.target = target; swapTemp.callAmount = callAmount; swapTemp.receiver = callParam.receiver; } catch {} } } if (swapTemp.swapAmount > swapTemp.callAmount) { Helper._transfer(swapTemp.swapToken, swapTemp.receiver, (swapTemp.swapAmount - swapTemp.callAmount)); } emit RemoteSwapAndCall( _orderId, swapTemp.receiver, swapTemp.target, swapTemp.srcToken, swapTemp.swapToken, swapTemp.srcAmount, swapTemp.swapAmount, swapTemp.callAmount, swapTemp.fromChain, swapTemp.toChain, swapTemp.from ); } function doRemoteSwap( Helper.SwapParam memory _swap, address _srcToken, uint256 _amount ) external returns (address target, address dstToken, uint256 dstAmount) { require(msg.sender == address(this)); bool result; (result, dstToken, dstAmount) = _makeSwap(_amount, _srcToken, _swap); require(result, ErrorMessage.SWAP_FAIL); require(dstAmount >= _swap.minReturnAmount, ErrorMessage.RECEIVE_LOW); target = _swap.executor; } function doRemoteCall( Helper.CallbackParam memory _callParam, address _callToken, uint256 _amount ) external returns (address target, uint256 callAmount) { require(msg.sender == address(this)); bool result; (result, callAmount) = _callBack(_amount, _callToken, _callParam); require(result, ErrorMessage.CALL_FAIL); target = _callParam.target; } function _doBridge( address _sender, address _token, uint256 _value, BridgeParam memory _bridge ) internal returns (bytes32 _orderId) { if (Helper._isNative(_token)) { _orderId = IButterMosV2(mosAddress).swapOutNative{value: _value}( _sender, _bridge.receiver, _bridge.toChain, _bridge.data ); } else { IERC20(_token).safeApprove(mosAddress, _value); _orderId = IButterMosV2(mosAddress).swapOutToken( _sender, _token, _bridge.receiver, _value, _bridge.toChain, _bridge.data ); } } function setGasForReFund(uint256 _gasForReFund) external onlyOwner { gasForReFund = _gasForReFund; emit SetGasForReFund(_gasForReFund); } function setMosAddress(address _mosAddress) public onlyOwner returns (bool) { _setMosAddress(_mosAddress); return true; } function _setMosAddress(address _mosAddress) internal returns (bool) { require(_mosAddress.isContract(), ErrorMessage.NOT_CONTRACT); mosAddress = _mosAddress; emit SetMos(_mosAddress); return true; } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IButterMosV2 { function swapOutToken( address _sender, address _token, // src token bytes memory _to, uint256 _amount, uint256 _toChain, // target chain id bytes calldata _swapData ) external returns (bytes32 orderId); function swapOutNative( address _sender, bytes memory _to, uint256 _toChain, // target chain id bytes calldata _swapData ) external payable returns (bytes32 orderId); function depositToken(address _token, address to, uint256 _amount) external; function depositNative(address _to) external payable; event SetButterRouterAddress(address indexed _newRouter); event mapTransferOut( uint256 indexed fromChain, uint256 indexed toChain, bytes32 orderId, bytes token, bytes from, bytes to, uint256 amount, bytes toChainToken ); event mapDepositOut( uint256 indexed fromChain, uint256 indexed toChain, bytes32 orderId, address token, bytes from, address to, uint256 amount ); event mapSwapOut( uint256 indexed fromChain, // from chain uint256 indexed toChain, // to chain bytes32 orderId, // order id bytes token, // token to transfer bytes from, // source chain from address bytes to, uint256 amount, bytes swapData // swap data, used on target chain dex. ); event mapSwapIn( uint256 indexed fromChain, uint256 indexed toChain, bytes32 indexed orderId, address token, bytes from, address toAddress, uint256 amountOut ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IButterReceiver { //_srcToken received token (wtoken or erc20 token) function onReceived( bytes32 _orderId, address _srcToken, uint256 _amount, uint256 _fromChain, bytes calldata _from, bytes calldata _payload ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./Ownable.sol"; /** * @dev Contract module which provides access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; // EIP-2612 is Final as of 2022-11-01. This file is deprecated. import "./IERC20Permit.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @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, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.21; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable2Step.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "../lib/ErrorMessage.sol"; import "../lib/Helper.sol"; abstract contract Router is Ownable2Step { using SafeERC20 for IERC20; using Address for address; uint256 public feeRate; uint256 public fixedFee; address public feeReceiver; address internal immutable wToken; uint256 internal nativeBalanceBeforeExec; uint256 private constant FEE_DENOMINATOR = 1000000; mapping(address => bool) public approved; event Approve(address indexed executor, bool indexed flag); event SetFee(address indexed receiver, uint256 indexed rate, uint256 indexed fixedf); event CollectFee( address indexed token, address indexed receiver, uint256 indexed amount, bytes32 transferId, FeeType feeType ); enum FeeType { FIXED, PROPORTION } // use to solve deep stack struct SwapTemp { address srcToken; address swapToken; uint256 srcAmount; uint256 swapAmount; bytes32 transferId; address receiver; address target; uint256 callAmount; uint256 fromChain; uint256 toChain; bytes from; FeeType feeType; } event SwapAndCall( address indexed from, address indexed receiver, address indexed target, bytes32 transferId, address originToken, address swapToken, uint256 originAmount, uint256 swapAmount, uint256 callAmount ); modifier transferIn( address token, uint256 amount, bytes memory permitData ) { require(amount > 0, ErrorMessage.ZERO_IN); if (permitData.length > 0) { Helper._permit(permitData); } nativeBalanceBeforeExec = address(this).balance - msg.value; if (Helper._isNative(token)) { require(msg.value >= amount, ErrorMessage.FEE_MISMATCH); } else { SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount); } _; nativeBalanceBeforeExec = 0; } constructor(address _owner, address _wToken) payable { require(_owner != Helper.ZERO_ADDRESS, ErrorMessage.ZERO_ADDR); require(_wToken.isContract(), ErrorMessage.NOT_CONTRACT); wToken = _wToken; _transferOwnership(_owner); } function _doSwapAndCall( bytes memory _swapData, bytes memory _callbackData, address _srcToken, uint256 _amount ) internal returns (address receiver, address target, address dstToken, uint256 swapOutAmount, uint256 callAmount) { bool result; swapOutAmount = _amount; dstToken = _srcToken; if (_swapData.length > 0) { Helper.SwapParam memory swap = abi.decode(_swapData, (Helper.SwapParam)); (result, dstToken, swapOutAmount) = _makeSwap(_amount, _srcToken, swap); require(result, ErrorMessage.SWAP_FAIL); require(swapOutAmount >= swap.minReturnAmount, ErrorMessage.RECEIVE_LOW); receiver = swap.receiver; target = swap.executor; } if (_callbackData.length > 0) { Helper.CallbackParam memory callParam = abi.decode(_callbackData, (Helper.CallbackParam)); (result, callAmount) = _callBack(swapOutAmount, dstToken, callParam); require(result, ErrorMessage.CALL_FAIL); receiver = callParam.receiver; target = callParam.target; } } function setFee(address _feeReceiver, uint256 _feeRate, uint256 _fixedFee) external onlyOwner { require(_feeReceiver != Helper.ZERO_ADDRESS, ErrorMessage.ZERO_ADDR); require(_feeRate < FEE_DENOMINATOR); feeReceiver = _feeReceiver; feeRate = _feeRate; fixedFee = _fixedFee; emit SetFee(_feeReceiver, _feeRate, fixedFee); } function getFee( uint256 _amount, address _token, FeeType _feeType ) external view returns (address _feeReceiver, address _feeToken, uint256 _fee, uint256 _feeAfter) { if (feeReceiver == Helper.ZERO_ADDRESS) { return (Helper.ZERO_ADDRESS, Helper.ZERO_ADDRESS, 0, _amount); } if (_feeType == FeeType.FIXED) { _feeToken = Helper.ZERO_ADDRESS; _fee = fixedFee; if (!Helper._isNative(_token)) { _feeAfter = _amount; } else { _feeAfter = _amount - _fee; } } else { _feeToken = _token; _fee = (_amount * feeRate) / FEE_DENOMINATOR; _feeAfter = _amount - _fee; } _feeReceiver = feeReceiver; } function getInputBeforeFee( uint256 _amountAfterFee, address _token, FeeType _feeType ) external view returns (uint256 _input, address _feeReceiver, address _feeToken, uint256 _fee) { if (feeReceiver == Helper.ZERO_ADDRESS) { return (_amountAfterFee, Helper.ZERO_ADDRESS, Helper.ZERO_ADDRESS, 0); } if (_feeType == FeeType.FIXED) { _feeToken = Helper.ZERO_ADDRESS; _fee = fixedFee; if (!Helper._isNative(_token)) { _input = _amountAfterFee; } else { _input = _amountAfterFee + _fee; } } else { _feeToken = _token; _input = (_amountAfterFee * FEE_DENOMINATOR) / (FEE_DENOMINATOR - feeRate) + 1; _fee = _input - _amountAfterFee; } _feeReceiver = feeReceiver; } function _collectFee( address _token, uint256 _amount, bytes32 transferId, FeeType _feeType ) internal returns (uint256 _fee, uint256 _remain) { if (feeReceiver == Helper.ZERO_ADDRESS) { _remain = _amount; return (_fee, _remain); } if (_feeType == FeeType.FIXED) { _fee = fixedFee; if (Helper._isNative(_token)) { require(msg.value > fixedFee, ErrorMessage.FEE_LOWER); _remain = _amount - _fee; } else { require(msg.value >= fixedFee, ErrorMessage.FEE_MISMATCH); _remain = _amount; } _token = Helper.NATIVE_ADDRESS; } else { _fee = (_amount * feeRate) / FEE_DENOMINATOR; _remain = _amount - _fee; } if (_fee > 0) { Helper._transfer(_token, feeReceiver, _fee); emit CollectFee(_token, feeReceiver, _fee, transferId, _feeType); } } function _callBack( uint256 _amount, address _token, Helper.CallbackParam memory _callParam ) internal returns (bool _result, uint256 _callAmount) { require(approved[_callParam.target], ErrorMessage.NO_APPROVE); (_result, _callAmount) = Helper._callBack(_amount, _token, _callParam); require(address(this).balance >= nativeBalanceBeforeExec, ErrorMessage.NATIVE_VALUE_OVERSPEND); } function _makeSwap( uint256 _amount, address _srcToken, Helper.SwapParam memory _swap ) internal returns (bool _result, address _dstToken, uint256 _returnAmount) { require(approved[_swap.executor] || _swap.executor == wToken, ErrorMessage.NO_APPROVE); if (_swap.executor == wToken) { bytes4 sig = Helper._getFirst4Bytes(_swap.data); //0x2e1a7d4d -> withdraw(uint256 wad) 0xd0e30db0 -> deposit() if (sig != bytes4(0x2e1a7d4d) && sig != bytes4(0xd0e30db0)) { return (false, _srcToken, 0); } } (_result, _dstToken, _returnAmount) = Helper._makeSwap(_amount, _srcToken, _swap); } function setAuthorization(address[] calldata _executors, bool _flag) external onlyOwner { require(_executors.length > 0, ErrorMessage.DATA_EMPTY); for (uint i = 0; i < _executors.length; i++) { require(_executors[i].isContract(), ErrorMessage.NOT_CONTRACT); approved[_executors[i]] = _flag; emit Approve(_executors[i], _flag); } } function rescueFunds(address _token, uint256 _amount) external onlyOwner { Helper._transfer(_token, msg.sender, _amount); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; library ErrorMessage { string internal constant ZERO_IN = "ButterRouterV2: zero in"; string internal constant FEE_MISMATCH = "ButterRouterV2: fee mismatch"; string internal constant FEE_LOWER = "ButterRouterV2: lower than fee"; string internal constant ZERO_ADDR = "ButterRouterV2: zero addr"; string internal constant NOT_CONTRACT = "ButterRouterV2: not contract"; string internal constant BRIDGE_REQUIRE = "ButterRouterV2: bridge data required"; string internal constant RECEIVE_LOW = "ButterRouterV2: receive too low"; string internal constant SWAP_FAIL = "ButterRouterV2: swap failed"; string internal constant SWAP_REQUIRE = "ButterRouterV2: swap data required"; string internal constant CALL_AMOUNT_INVALID = "ButterRouterV2: callback amount invalid"; string internal constant CALL_FAIL = "ButterRouterV2: callback failed"; string internal constant MOS_ONLY = "ButterRouterV2: mos only"; string internal constant DATA_EMPTY = "ButterRouterV2: data empty"; string internal constant NO_APPROVE = "ButterRouterV2: not approved"; string internal constant NATIVE_VALUE_OVERSPEND = "ButterRouterV2: native value overspend"; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; library Helper { using SafeERC20 for IERC20; address internal constant ZERO_ADDRESS = address(0); address internal constant NATIVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; struct CallbackParam { address target; address approveTo; uint256 offset; uint256 extraNativeAmount; address receiver; bytes data; } struct SwapParam { uint8 dexType; address executor; address approveTo; address receiver; address dstToken; uint256 minReturnAmount; bytes data; } function _isNative(address token) internal pure returns (bool) { return (token == ZERO_ADDRESS || token == NATIVE_ADDRESS); } function _getBalance(address _token, address _account) internal view returns (uint256) { if (_isNative(_token)) { return _account.balance; } else { return IERC20(_token).balanceOf(_account); } } function _transfer(address _token, address _to, uint256 _amount) internal { if (_isNative(_token)) { Address.sendValue(payable(_to), _amount); } else { IERC20(_token).safeTransfer(_to, _amount); } } function _safeWithdraw(address _wToken, uint _value) internal returns (bool) { (bool success, bytes memory data) = _wToken.call(abi.encodeWithSelector(0x2e1a7d4d, _value)); return (success && (data.length == 0 || abi.decode(data, (bool)))); } function _getFirst4Bytes(bytes memory data) internal pure returns (bytes4 outBytes4) { if (data.length == 0) { return 0x0; } assembly { outBytes4 := mload(add(data, 32)) } } function _makeSwap( uint256 _amount, address _srcToken, SwapParam memory _swap ) internal returns (bool _result, address _dstToken, uint256 _returnAmount) { _dstToken = _swap.dstToken; uint256 nativeValue = 0; bool isNative = Helper._isNative(_srcToken); if (isNative) { nativeValue = _amount; } else { IERC20(_srcToken).safeApprove(_swap.approveTo, 0); IERC20(_srcToken).safeApprove(_swap.approveTo, _amount); } _returnAmount = Helper._getBalance(_dstToken, address(this)); (_result, ) = _swap.executor.call{value: nativeValue}(_swap.data); _returnAmount = Helper._getBalance(_dstToken, address(this)) - _returnAmount; if (!isNative) { IERC20(_srcToken).safeApprove(_swap.approveTo, 0); } } function _callBack( uint256 _amount, address _token, CallbackParam memory _callParam ) internal returns (bool _result, uint256 _callAmount) { _callAmount = Helper._getBalance(_token, address(this)); uint256 offset = _callParam.offset; bytes memory callDatas = _callParam.data; if (offset != 0) { assembly { mstore(add(callDatas, offset), _amount) } } if (Helper._isNative(_token)) { (_result, ) = _callParam.target.call{value: _amount}(callDatas); } else { if (_amount != 0) IERC20(_token).safeIncreaseAllowance(_callParam.approveTo, _amount); // this contract not save money make sure send value can cover this (_result, ) = _callParam.target.call{value: _callParam.extraNativeAmount}(callDatas); if (_amount != 0) IERC20(_token).safeApprove(_callParam.approveTo, 0); } _callAmount = _callAmount - Helper._getBalance(_token, address(this)); } function _permit(bytes memory _data) internal { ( address token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) = abi.decode(_data, (address, address, address, uint256, uint256, uint8, bytes32, bytes32)); SafeERC20.safePermit(IERC20Permit(token), owner, spender, value, deadline, v, r, s); } }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_mosAddress","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_wToken","type":"address"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":true,"internalType":"bool","name":"flag","type":"bool"}],"name":"Approve","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":false,"internalType":"enum Router.FeeType","name":"feeType","type":"uint8"}],"name":"CollectFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"address","name":"originToken","type":"address"},{"indexed":false,"internalType":"address","name":"swapToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"originAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"swapAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"callAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fromChain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChain","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"from","type":"bytes"}],"name":"RemoteSwapAndCall","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"uint256","name":"rate","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"fixedf","type":"uint256"}],"name":"SetFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_gasForReFund","type":"uint256"}],"name":"SetGasForReFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"mos","type":"address"}],"name":"SetMos","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"originToken","type":"address"},{"indexed":false,"internalType":"address","name":"bridgeToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"originAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bridgeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fromChain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChain","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"to","type":"bytes"}],"name":"SwapAndBridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"originToken","type":"address"},{"indexed":false,"internalType":"address","name":"swapToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"originAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"swapAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"callAmount","type":"uint256"}],"name":"SwapAndCall","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"approveTo","type":"address"},{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"extraNativeAmount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Helper.CallbackParam","name":"_callParam","type":"tuple"},{"internalType":"address","name":"_callToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"doRemoteCall","outputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"callAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint8","name":"dexType","type":"uint8"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"address","name":"approveTo","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"uint256","name":"minReturnAmount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Helper.SwapParam","name":"_swap","type":"tuple"},{"internalType":"address","name":"_srcToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"doRemoteSwap","outputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"uint256","name":"dstAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fixedFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasForReFund","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"enum Router.FeeType","name":"_feeType","type":"uint8"}],"name":"getFee","outputs":[{"internalType":"address","name":"_feeReceiver","type":"address"},{"internalType":"address","name":"_feeToken","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"uint256","name":"_feeAfter","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountAfterFee","type":"uint256"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"enum Router.FeeType","name":"_feeType","type":"uint8"}],"name":"getInputBeforeFee","outputs":[{"internalType":"uint256","name":"_input","type":"uint256"},{"internalType":"address","name":"_feeReceiver","type":"address"},{"internalType":"address","name":"_feeToken","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mosAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_orderId","type":"bytes32"},{"internalType":"address","name":"_srcToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_fromChain","type":"uint256"},{"internalType":"bytes","name":"_from","type":"bytes"},{"internalType":"bytes","name":"_swapAndCall","type":"bytes"}],"name":"onReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"rescueFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_executors","type":"address[]"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"setAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeReceiver","type":"address"},{"internalType":"uint256","name":"_feeRate","type":"uint256"},{"internalType":"uint256","name":"_fixedFee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasForReFund","type":"uint256"}],"name":"setGasForReFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_mosAddress","type":"address"}],"name":"setMosAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_srcToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_swapData","type":"bytes"},{"internalType":"bytes","name":"_bridgeData","type":"bytes"},{"internalType":"bytes","name":"_permitData","type":"bytes"}],"name":"swapAndBridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_transferId","type":"bytes32"},{"internalType":"address","name":"_srcToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"enum Router.FeeType","name":"_feeType","type":"uint8"},{"internalType":"bytes","name":"_swapData","type":"bytes"},{"internalType":"bytes","name":"_callbackData","type":"bytes"},{"internalType":"bytes","name":"_permitData","type":"bytes"}],"name":"swapAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a06040526201388060095560405162003e8d38038062003e8d8339810160408190526200002d9162000277565b81816200003a3362000136565b60408051808201909152601981527f427574746572526f7574657256323a207a65726f20616464720000000000000060208201526001600160a01b038316620000a15760405162461bcd60e51b8152600401620000989190620002c1565b60405180910390fd5b5060408051808201909152601c81527f427574746572526f7574657256323a206e6f7420636f6e74726163740000000060208201526001600160a01b0382163b620001015760405162461bcd60e51b8152600401620000989190620002c1565b506001600160a01b0381166080526200011a8262000136565b505060016007556200012c8362000154565b5050505062000311565b600180546001600160a01b031916905562000151816200020a565b50565b60006001600160a01b0382163b15156040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e74726163740000000081525090620001ba5760405162461bcd60e51b8152600401620000989190620002c1565b50600880546001600160a01b0319166001600160a01b0384169081179091556040517ff43456bb773c1af890fa668fc6aabe2ea4c3141afd9e1c679f2a7d62b5a33d1790600090a2506001919050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200027257600080fd5b919050565b6000806000606084860312156200028d57600080fd5b62000298846200025a565b9250620002a8602085016200025a565b9150620002b8604085016200025a565b90509250925092565b600060208083528351808285015260005b81811015620002f057858101830151858201604001528201620002d2565b506000604082860101526040601f19601f8301168501019250505092915050565b608051613b596200033460003960008181611ab20152611b410152613b596000f3fe6080604052600436106101445760003560e01c80638da5cb5b116100b6578063d904371e1161006f578063d904371e146103c9578063e30c3978146103e9578063ecc847d314610407578063f2fde38b1461041a578063f78f24a71461043a578063f848a5741461048557600080fd5b80638da5cb5b1461030f57806391792d5b1461032d578063978bbdb914610343578063b3f0067414610359578063c1b1660e14610379578063d8b964e61461039957600080fd5b8063536f4cfe11610108578063536f4cfe1461022e5780635dc4ba081461024e578063715018a61461028d57806378e3214f146102a257806379ba5097146102c25780638cbafe0a146102d757600080fd5b80632344e655146101505780632b8b7b4b14610172578063451559a9146101a7578063480a3411146101f75780634e36b11c1461020a57600080fd5b3661014b57005b600080fd5b34801561015c57600080fd5b5061017061016b366004612c52565b6104cb565b005b34801561017e57600080fd5b5061019261018d366004612cf0565b610950565b60405190151581526020015b60405180910390f35b3480156101b357600080fd5b506101c76101c2366004612d23565b61096e565b60405161019e94939291909384526001600160a01b03928316602085015291166040830152606082015260800190565b610170610205366004612d61565b610a3b565b34801561021657600080fd5b5061022060095481565b60405190815260200161019e565b34801561023a57600080fd5b50610170610249366004612df5565b610df6565b34801561025a57600080fd5b5061026e610269366004612f1b565b610e31565b604080516001600160a01b03909316835260208301919091520161019e565b34801561029957600080fd5b50610170610eb0565b3480156102ae57600080fd5b506101706102bd366004612ff1565b610ec4565b3480156102ce57600080fd5b50610170610edb565b3480156102e357600080fd5b506008546102f7906001600160a01b031681565b6040516001600160a01b03909116815260200161019e565b34801561031b57600080fd5b506000546001600160a01b03166102f7565b34801561033957600080fd5b5061022060035481565b34801561034f57600080fd5b5061022060025481565b34801561036557600080fd5b506004546102f7906001600160a01b031681565b34801561038557600080fd5b5061017061039436600461301d565b610f55565b3480156103a557600080fd5b506101926103b4366004612cf0565b60066020526000908152604090205460ff1681565b3480156103d557600080fd5b506101706103e4366004613060565b611022565b3480156103f557600080fd5b506001546001600160a01b03166102f7565b6101706104153660046130e5565b6111de565b34801561042657600080fd5b50610170610435366004612cf0565b611569565b34801561044657600080fd5b5061045a610455366004612d23565b6115da565b604080516001600160a01b03958616815294909316602085015291830152606082015260800161019e565b34801561049157600080fd5b506104a56104a0366004613277565b611690565b604080516001600160a01b0394851681529390921660208401529082015260600161019e565b6104d3611764565b6104db612b89565b6001600160a01b0388168082526040808301899052602080840192909252606083018990526101008301889052466101208401528051601f87018390048302810183019091528581529086908690819084018382808284376000920191909152505050506101408201524760055560085460408051808201909152601881527f427574746572526f7574657256323a206d6f73206f6e6c7900000000000000006020820152906001600160a01b031633146105b25760405162461bcd60e51b81526004016105a99190613320565b60405180910390fd5b50866105c28260000151306117bd565b10156040518060400160405280601f8152602001600080516020613b04833981519152815250906106065760405162461bcd60e51b81526004016105a99190613320565b5060008061061684860186613333565b9150915060008151835161062a91906133ac565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b8152509061067c5760405162461bcd60e51b81526004016105a99190613320565b506009546001906000906106919060026133bf565b84519091501561077c576000848060200190518101906106b19190613431565b60608101516001600160a01b031660a08801529050815a111561077a57306001600160a01b031663f848a5746009545a6106eb91906134fc565b8389600001518a604001516040518563ffffffff1660e01b81526004016107149392919061350f565b60606040518083038160008887f193505050508015610750575060408051601f3d908101601f1916820190925261074d918101906135ba565b60015b61075d576000925061077a565b6001600160a01b0391821660208a0152911660c088015260608701525b505b82511561087c5760008380602001905181019061079991906135fd565b60a08701519091506001600160a01b03166107c25760808101516001600160a01b031660a08701525b8280156107ce5750815a115b1561087a57306001600160a01b0316635dc4ba086009545a6107f091906134fc565b8389602001518a606001516040518563ffffffff1660e01b8152600401610819939291906136b8565b604080518083038160008887f193505050508015610854575060408051601f3d908101601f1916820190925261085191810190613729565b60015b1561087a576001600160a01b0391821660c089015260e088015260808201511660a08701525b505b8460e00151856060015111156108b2576108b285602001518660a001518760e0015188606001516108ad91906134fc565b611851565b8460c001516001600160a01b03168560a001516001600160a01b03168e7f593e4dbcb8f7312fc3bdd77e2095da131a6e1993f37752d12576d04e1f7253b4886000015189602001518a604001518b606001518c60e001518d61010001518e61012001518f610140015160405161092f989796959493929190613757565b60405180910390a450505050506109466001600755565b5050505050505050565b600061095a611889565b610963826118e3565b50600190505b919050565b6004546000908190819081906001600160a01b031661099857508592506000915081905080610a32565b60008560018111156109ac576109ac6137b0565b036109df5750506003546000906109c286611996565b6109ce57869350610a23565b6109d881886133ac565b9350610a23565b6002548692506109f290620f42406134fc565b6109ff620f4240896133bf565b610a0991906137c6565b610a149060016133ac565b9350610a2087856134fc565b90505b6004546001600160a01b031692505b93509350935093565b610a43611764565b878783838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526017815276213aba3a32b92937baba32b92b191d103d32b9379034b760491b602082015291505082610ac85760405162461bcd60e51b81526004016105a99190613320565b50805115610ad957610ad9816119cf565b610ae334476134fc565b600555610aef83611996565b15610b5257813410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d617463680000000081525090610b4c5760405162461bcd60e51b81526004016105a99190613320565b50610b5e565b610b5e83333085611a1a565b6000610b6a878a6133ac565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b81525090610bbc5760405162461bcd60e51b81526004016105a99190613320565b50610bc5612b89565b6001600160a01b038c16808252604082018c9052602082015260608082018c90528915610d33576000610bfa8b8d018d6137e8565b90506000610c118460400151856000015184611a85565b60608701526001600160a01b031660208087019190915260408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c656400000000009181019190915290915081610c7f5760405162461bcd60e51b81526004016105a99190613320565b508160a00151846060015110156040518060400160405280601f8152602001600080516020613b0483398151915281525090610cce5760405162461bcd60e51b81526004016105a99190613320565b5089158015610ce1575060008460600151115b15610d3057606082810151604051911b6bffffffffffffffffffffffff191660208201526034016040516020818303038152906040529250610d30846020015183606001518660600151611851565b50505b60008815610d76576000610d498a8c018c61381c565b8051610120860152602080820151908601516060870151919550919250610d7291339184611bf3565b9150505b82600001516001600160a01b0316336001600160a01b0316827f140fc1ae4910fc65859bbe978cf17402f862c5bd87a15aa3a0894d5aa50b0b06866020015187604001518860600151468a61012001518a604051610dd9969594939291906138cc565b60405180910390a450506000600555506109469250611882915050565b610dfe611889565b600981905560405181907ff47543a7cab136b12cca0a2ecd728c9d1943f57b923b98db48725d2b76dd4da990600090a250565b600080333014610e4057600080fd5b6000610e4d848688611d35565b60408051808201909152601f81527f427574746572526f7574657256323a2063616c6c6261636b206661696c656400602082015290935090915081610ea55760405162461bcd60e51b81526004016105a99190613320565b505093519492505050565b610eb8611889565b610ec26000611e02565b565b610ecc611889565b610ed7823383611851565b5050565b60015433906001600160a01b03168114610f495760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016105a9565b610f5281611e02565b50565b610f5d611889565b60408051808201909152601981527f427574746572526f7574657256323a207a65726f20616464720000000000000060208201526001600160a01b038416610fb85760405162461bcd60e51b81526004016105a99190613320565b50620f42408210610fc857600080fd5b600480546001600160a01b0319166001600160a01b03851690811790915560028390556003829055604051829184917f17906aa05b055ced1cea92b104912638c3ec8c90eec152fca6f36fbd8becca1d90600090a4505050565b61102a611889565b60408051808201909152601a815279427574746572526f7574657256323a206461746120656d70747960301b6020820152826110795760405162461bcd60e51b81526004016105a99190613320565b5060005b828110156111d8576110be84848381811061109a5761109a613911565b90506020020160208101906110af9190612cf0565b6001600160a01b03163b151590565b6040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e747261637400000000815250906111125760405162461bcd60e51b81526004016105a99190613320565b50816006600086868581811061112a5761112a613911565b905060200201602081019061113f9190612cf0565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905581151584848381811061117c5761117c613911565b90506020020160208101906111919190612cf0565b6001600160a01b03167f1f478f1e5aee36a892d86e821aba410dc0934cb0ebd0241dd75370833884545360405160405180910390a3806111d081613927565b91505061107d565b50505050565b6111e6611764565b888883838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526017815276213aba3a32b92937baba32b92b191d103d32b9379034b760491b60208201529150508261126b5760405162461bcd60e51b81526004016105a99190613320565b5080511561127c5761127c816119cf565b61128634476134fc565b60055561129283611996565b156112f557813410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d6174636800000000815250906112ef5760405162461bcd60e51b81526004016105a99190613320565b50611301565b61130183333085611a1a565b611309612b89565b6001600160a01b038d168152604081018c9052608081018e905261016081018b600181111561133a5761133a6137b0565b9081600181111561134d5761134d6137b0565b905250600061135c888b6133ac565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b815250906113ae5760405162461bcd60e51b81526004016105a99190613320565b506113cc816000015182604001518360800151846101600151611e1b565b606083015250604080516020601f8c018190048102820181019092528a815261144c918c908c908190840183828082843760009201919091525050604080516020601f8e018190048102820181019092528c815292508c91508b908190840183828082843760009201919091525050855160608701519092509050611feb565b60e08601819052606086018290526001600160a01b03928316602087015292821660c0860152921660a084015210156114a0576114a081602001518260a001518360e0015184606001516108ad91906134fc565b8060c001516001600160a01b03168160a001516001600160a01b0316336001600160a01b03167f54592234b1278d8a9675f22721443e0b9f8a1f4410b55bf6753330073b55e3ef846080015185600001518660200151876040015188606001518960e00151604051611546969594939291909586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b60405180910390a450506000600555505060016007555b50505050505050505050565b611571611889565b600180546001600160a01b0383166001600160a01b031990911681179091556115a26000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6004546000908190819081906001600160a01b031661160457506000925082915081905085610a32565b6000856001811115611618576116186137b0565b0361164b5760009250600354915061162f86611996565b61163a575085611679565b61164482886134fc565b9050611679565b859250620f42406002548861166091906133bf565b61166a91906137c6565b915061167682886134fc565b90505b6004546001600160a01b0316935093509350935093565b600080803330146116a057600080fd5b60006116ad858789611a85565b60408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c6564000000000060208201529195509350909150816117075760405162461bcd60e51b81526004016105a99190613320565b508660a001518210156040518060400160405280601f8152602001600080516020613b04833981519152815250906117525760405162461bcd60e51b81526004016105a99190613320565b50866020015193505093509350939050565b6002600754036117b65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105a9565b6002600755565b60006117c883611996565b156117de57506001600160a01b0381163161184b565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa158015611824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118489190613940565b90505b92915050565b61185a83611996565b1561186e576118698282612174565b505050565b6118696001600160a01b038416838361228d565b6001600755565b6000546001600160a01b03163314610ec25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105a9565b60006001600160a01b0382163b15156040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e747261637400000000815250906119465760405162461bcd60e51b81526004016105a99190613320565b50600880546001600160a01b0319166001600160a01b0384169081179091556040517ff43456bb773c1af890fa668fc6aabe2ea4c3141afd9e1c679f2a7d62b5a33d1790600090a2506001919050565b60006001600160a01b038216158061184b57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b600080600080600080600080888060200190518101906119ef9190613959565b97509750975097509750975097509750611a0f88888888888888886122bd565b505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526111d89085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612487565b6020808201516001600160a01b03166000908152600690915260408120548190819060ff1680611aea57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031684602001516001600160a01b0316145b6040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420617070726f7665640000000081525090611b3e5760405162461bcd60e51b81526004016105a99190613320565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031684602001516001600160a01b031603611bd7576000611b8b8560c0015161255c565b90506001600160e01b03198116632e1a7d4d60e01b14801590611bbf57506001600160e01b03198116630d0e30db60e41b14155b15611bd557600086600093509350935050611bea565b505b611be2868686612577565b919450925090505b93509350939050565b6000611bfe84611996565b15611c8b57600854602083015183516040808601519051636a9a8d5560e11b81526001600160a01b039094169363d5351aaa938893611c41938c936004016139df565b60206040518083038185885af1158015611c5f573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611c849190613940565b9050611d2d565b600854611ca5906001600160a01b03868116911685612687565b600854602083015183516040808601519051632e267e4160e21b81526001600160a01b039094169363b899f90493611ce7938b938b938b929190600401613a1b565b6020604051808303816000875af1158015611d06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2a9190613940565b90505b949350505050565b80516001600160a01b03166000908152600660209081526040808320548151808301909252601c82527f427574746572526f7574657256323a206e6f7420617070726f7665640000000092820192909252829160ff16611da85760405162461bcd60e51b81526004016105a99190613320565b50611db485858561279c565b8092508193505050600554471015604051806060016040528060268152602001613ade6026913990611df95760405162461bcd60e51b81526004016105a99190613320565b50935093915050565b600180546001600160a01b0319169055610f5281612904565b60045460009081906001600160a01b0316611e37575083611fe2565b6000836001811115611e4b57611e4b6137b0565b03611f49576003549150611e5e86611996565b15611ece5760035434116040518060400160405280601e81526020017f427574746572526f7574657256323a206c6f776572207468616e20666565000081525090611ebc5760405162461bcd60e51b81526004016105a99190613320565b50611ec782866134fc565b9050611f2d565b6003543410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d617463680000000081525090611f285760405162461bcd60e51b81526004016105a99190613320565b508490505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee9550611f74565b620f424060025486611f5b91906133bf565b611f6591906137c6565b9150611f7182866134fc565b90505b8115611fe257600454611f929087906001600160a01b031684611851565b60045460405183916001600160a01b0390811691908916907fcc4044b4bd9f077089a3cbea5f01bcacf584f45336b1b50a8fb5f5e552da5f1490611fd99089908990613a72565b60405180910390a45b94509492505050565b835160009081908490849083908190156120d85760008a8060200190518101906120159190613431565b9050612022888a83611a85565b60408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c65640000000000602082015291975095509092508261207c5760405162461bcd60e51b81526004016105a99190613320565b508060a001518410156040518060400160405280601f8152602001600080516020613b04833981519152815250906120c75760405162461bcd60e51b81526004016105a99190613320565b508060600151965080602001519550505b885115612168576000898060200190518101906120f591906135fd565b9050612102848683611d35565b60408051808201909152601f81527f427574746572526f7574657256323a2063616c6c6261636b206661696c65640060208201529094509092508261215a5760405162461bcd60e51b81526004016105a99190613320565b506080810151905190965094505b50945094509450945094565b804710156121c45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016105a9565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612211576040519150601f19603f3d011682016040523d82523d6000602084013e612216565b606091505b50509050806118695760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016105a9565b6040516001600160a01b03831660248201526044810182905261186990849063a9059cbb60e01b90606401611a4e565b604051623f675f60e91b81526001600160a01b038881166004830152600091908a1690637ecebe0090602401602060405180830381865afa158015612306573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232a9190613940565b60405163d505accf60e01b81526001600160a01b038a811660048301528981166024830152604482018990526064820188905260ff8716608483015260a4820186905260c48201859052919250908a169063d505accf9060e401600060405180830381600087803b15801561239e57600080fd5b505af11580156123b2573d6000803e3d6000fd5b5050604051623f675f60e91b81526001600160a01b038b81166004830152600093508c169150637ecebe0090602401602060405180830381865afa1580156123fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124229190613940565b905061242f8260016133ac565b811461155d5760405162461bcd60e51b815260206004820152602160248201527f5361666545524332303a207065726d697420646964206e6f74207375636365656044820152601960fa1b60648201526084016105a9565b60006124dc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166129549092919063ffffffff16565b90508051600014806124fd5750808060200190518101906124fd9190613aa4565b6118695760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105a9565b6000815160000361256f57506000919050565b506020015190565b608081015160009081808061258b87611996565b9050801561259b578791506125d0565b60408601516125b6906001600160a01b038916906000612687565b60408601516125d0906001600160a01b038916908a612687565b6125da84306117bd565b925085602001516001600160a01b0316828760c001516040516125fd9190613ac1565b60006040518083038185875af1925050503d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b5050809550508261265085306117bd565b61265a91906134fc565b92508061267c57604086015161267c906001600160a01b038916906000612687565b505093509350939050565b8015806127015750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156126db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ff9190613940565b155b61276c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016105a9565b6040516001600160a01b03831660248201526044810182905261186990849063095ea7b360e01b90606401611a4e565b6000806127a984306117bd565b604084015160a08501519192509081156127c35786828201525b6127cc86611996565b1561283b5784600001516001600160a01b031687826040516127ee9190613ac1565b60006040518083038185875af1925050503d806000811461282b576040519150601f19603f3d011682016040523d82523d6000602084013e612830565b606091505b5050809450506128e4565b861561285b57602085015161285b906001600160a01b0388169089612963565b84600001516001600160a01b031685606001518260405161287c9190613ac1565b60006040518083038185875af1925050503d80600081146128b9576040519150601f19603f3d011682016040523d82523d6000602084013e6128be565b606091505b509094505086156128e45760208501516128e4906001600160a01b038816906000612687565b6128ee86306117bd565b6128f890846134fc565b92505050935093915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060611d2d8484600085612a10565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa1580156129b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129d79190613940565b90506111d88463095ea7b360e01b856129f086866133ac565b6040516001600160a01b0390921660248301526044820152606401611a4e565b606082471015612a715760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105a9565b600080866001600160a01b03168587604051612a8d9190613ac1565b60006040518083038185875af1925050503d8060008114612aca576040519150601f19603f3d011682016040523d82523d6000602084013e612acf565b606091505b5091509150612ae087838387612aeb565b979650505050505050565b60608315612b5a578251600003612b53576001600160a01b0385163b612b535760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105a9565b5081611d2d565b611d2d8383815115612b6f5781518083602001fd5b8060405162461bcd60e51b81526004016105a99190613320565b604080516101808101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201529061016082015290565b6001600160a01b0381168114610f5257600080fd5b803561096981612bea565b60008083601f840112612c1c57600080fd5b5081356001600160401b03811115612c3357600080fd5b602083019150836020828501011115612c4b57600080fd5b9250929050565b60008060008060008060008060c0898b031215612c6e57600080fd5b883597506020890135612c8081612bea565b9650604089013595506060890135945060808901356001600160401b0380821115612caa57600080fd5b612cb68c838d01612c0a565b909650945060a08b0135915080821115612ccf57600080fd5b50612cdc8b828c01612c0a565b999c989b5096995094979396929594505050565b600060208284031215612d0257600080fd5b8135612d0d81612bea565b9392505050565b80356002811061096957600080fd5b600080600060608486031215612d3857600080fd5b833592506020840135612d4a81612bea565b9150612d5860408501612d14565b90509250925092565b60008060008060008060008060a0898b031215612d7d57600080fd5b8835612d8881612bea565b97506020890135965060408901356001600160401b0380821115612dab57600080fd5b612db78c838d01612c0a565b909850965060608b0135915080821115612dd057600080fd5b612ddc8c838d01612c0a565b909650945060808b0135915080821115612ccf57600080fd5b600060208284031215612e0757600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715612e4657612e46612e0e565b60405290565b60405160e081016001600160401b0381118282101715612e4657612e46612e0e565b604051601f8201601f191681016001600160401b0381118282101715612e9657612e96612e0e565b604052919050565b60006001600160401b03821115612eb757612eb7612e0e565b50601f01601f191660200190565b600082601f830112612ed657600080fd5b8135612ee9612ee482612e9e565b612e6e565b818152846020838601011115612efe57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600060608486031215612f3057600080fd5b83356001600160401b0380821115612f4757600080fd5b9085019060c08288031215612f5b57600080fd5b612f63612e24565b8235612f6e81612bea565b81526020830135612f7e81612bea565b8060208301525060408301356040820152606083013560608201526080830135612fa781612bea565b608082015260a083013582811115612fbe57600080fd5b612fca89828601612ec5565b60a0830152509450612fe191505060208501612bff565b9150604084013590509250925092565b6000806040838503121561300457600080fd5b823561300f81612bea565b946020939093013593505050565b60008060006060848603121561303257600080fd5b833561303d81612bea565b95602085013595506040909401359392505050565b8015158114610f5257600080fd5b60008060006040848603121561307557600080fd5b83356001600160401b038082111561308c57600080fd5b818601915086601f8301126130a057600080fd5b8135818111156130af57600080fd5b8760208260051b85010111156130c457600080fd5b602092830195509350508401356130da81613052565b809150509250925092565b60008060008060008060008060008060e08b8d03121561310457600080fd5b8a35995060208b013561311681612bea565b985060408b0135975061312b60608c01612d14565b965060808b01356001600160401b038082111561314757600080fd5b6131538e838f01612c0a565b909850965060a08d013591508082111561316c57600080fd5b6131788e838f01612c0a565b909650945060c08d013591508082111561319157600080fd5b5061319e8d828e01612c0a565b915080935050809150509295989b9194979a5092959850565b60ff81168114610f5257600080fd5b8035610969816131b7565b600060e082840312156131e357600080fd5b6131eb612e4c565b90506131f6826131c6565b815261320460208301612bff565b602082015261321560408301612bff565b604082015261322660608301612bff565b606082015261323760808301612bff565b608082015260a082013560a082015260c08201356001600160401b0381111561325f57600080fd5b61326b84828501612ec5565b60c08301525092915050565b60008060006060848603121561328c57600080fd5b83356001600160401b038111156132a257600080fd5b6132ae868287016131d1565b93505060208401356132bf81612bea565b929592945050506040919091013590565b60005b838110156132eb5781810151838201526020016132d3565b50506000910152565b6000815180845261330c8160208601602086016132d0565b601f01601f19169290920160200192915050565b602081526000612d0d60208301846132f4565b6000806040838503121561334657600080fd5b82356001600160401b038082111561335d57600080fd5b61336986838701612ec5565b9350602085013591508082111561337f57600080fd5b5061338c85828601612ec5565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561184b5761184b613396565b808202811582820484141761184b5761184b613396565b8051610969816131b7565b805161096981612bea565b600082601f8301126133fd57600080fd5b815161340b612ee482612e9e565b81815284602083860101111561342057600080fd5b611d2d8260208301602087016132d0565b60006020828403121561344357600080fd5b81516001600160401b038082111561345a57600080fd5b9083019060e0828603121561346e57600080fd5b613476612e4c565b61347f836133d6565b815261348d602084016133e1565b602082015261349e604084016133e1565b60408201526134af606084016133e1565b60608201526134c0608084016133e1565b608082015260a083015160a082015260c0830151828111156134e157600080fd5b6134ed878286016133ec565b60c08301525095945050505050565b8181038181111561184b5761184b613396565b6060808252845160ff168282015260208501516001600160a01b03908116608084015260408601511660a083015284015160009061355860c08401826001600160a01b03169052565b5060808501516001600160a01b03811660e08401525060a085015161010083015260c085015160e06101208401526135946101408401826132f4565b9150506135ac60208301856001600160a01b03169052565b826040830152949350505050565b6000806000606084860312156135cf57600080fd5b83516135da81612bea565b60208501519093506135eb81612bea565b80925050604084015190509250925092565b60006020828403121561360f57600080fd5b81516001600160401b038082111561362657600080fd5b9083019060c0828603121561363a57600080fd5b613642612e24565b825161364d81612bea565b8152602083015161365d81612bea565b806020830152506040830151604082015260608301516060820152608083015161368681612bea565b608082015260a08301518281111561369d57600080fd5b6136a9878286016133ec565b60a08301525095945050505050565b60608152600060018060a01b03808651166060840152806020870151166080840152604086015160a0840152606086015160c08401528060808701511660e084015260a086015160c06101008501526137156101208501826132f4565b959091166020840152505060400152919050565b6000806040838503121561373c57600080fd5b825161374781612bea565b6020939093015192949293505050565b600061010060018060a01b03808c168452808b166020850152508860408401528760608401528660808401528560a08401528460c08401528060e08401526137a1818401856132f4565b9b9a5050505050505050505050565b634e487b7160e01b600052602160045260246000fd5b6000826137e357634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156137fa57600080fd5b81356001600160401b0381111561381057600080fd5b611d2d848285016131d1565b60006020828403121561382e57600080fd5b81356001600160401b038082111561384557600080fd5b908301906060828603121561385957600080fd5b60405160608101818110838211171561387457613874612e0e565b6040528235815260208301358281111561388d57600080fd5b61389987828601612ec5565b6020830152506040830135828111156138b157600080fd5b6138bd87828601612ec5565b60408301525095945050505050565b60018060a01b038716815285602082015284604082015283606082015282608082015260c060a0820152600061390560c08301846132f4565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161393957613939613396565b5060010190565b60006020828403121561395257600080fd5b5051919050565b600080600080600080600080610100898b03121561397657600080fd5b885161398181612bea565b60208a015190985061399281612bea565b60408a01519097506139a381612bea565b80965050606089015194506080890151935060a08901516139c3816131b7565b60c08a015160e0909a0151989b979a5095989497939692505050565b6001600160a01b0385168152608060208201819052600090613a03908301866132f4565b8460408401528281036060840152612ae081856132f4565b6001600160a01b0387811682528616602082015260c060408201819052600090613a47908301876132f4565b85606084015284608084015282810360a0840152613a6581856132f4565b9998505050505050505050565b8281526040810160028310613a9757634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b600060208284031215613ab657600080fd5b8151612d0d81613052565b60008251613ad38184602087016132d0565b919091019291505056fe427574746572526f7574657256323a206e61746976652076616c7565206f7665727370656e64427574746572526f7574657256323a207265636569766520746f6f206c6f7700a2646970667358221220bddbb247898d63d01101a703f56c97304a5f0673383c5206ab2de7759a7fa93864736f6c63430008150033000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d93000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Deployed Bytecode
0x6080604052600436106101445760003560e01c80638da5cb5b116100b6578063d904371e1161006f578063d904371e146103c9578063e30c3978146103e9578063ecc847d314610407578063f2fde38b1461041a578063f78f24a71461043a578063f848a5741461048557600080fd5b80638da5cb5b1461030f57806391792d5b1461032d578063978bbdb914610343578063b3f0067414610359578063c1b1660e14610379578063d8b964e61461039957600080fd5b8063536f4cfe11610108578063536f4cfe1461022e5780635dc4ba081461024e578063715018a61461028d57806378e3214f146102a257806379ba5097146102c25780638cbafe0a146102d757600080fd5b80632344e655146101505780632b8b7b4b14610172578063451559a9146101a7578063480a3411146101f75780634e36b11c1461020a57600080fd5b3661014b57005b600080fd5b34801561015c57600080fd5b5061017061016b366004612c52565b6104cb565b005b34801561017e57600080fd5b5061019261018d366004612cf0565b610950565b60405190151581526020015b60405180910390f35b3480156101b357600080fd5b506101c76101c2366004612d23565b61096e565b60405161019e94939291909384526001600160a01b03928316602085015291166040830152606082015260800190565b610170610205366004612d61565b610a3b565b34801561021657600080fd5b5061022060095481565b60405190815260200161019e565b34801561023a57600080fd5b50610170610249366004612df5565b610df6565b34801561025a57600080fd5b5061026e610269366004612f1b565b610e31565b604080516001600160a01b03909316835260208301919091520161019e565b34801561029957600080fd5b50610170610eb0565b3480156102ae57600080fd5b506101706102bd366004612ff1565b610ec4565b3480156102ce57600080fd5b50610170610edb565b3480156102e357600080fd5b506008546102f7906001600160a01b031681565b6040516001600160a01b03909116815260200161019e565b34801561031b57600080fd5b506000546001600160a01b03166102f7565b34801561033957600080fd5b5061022060035481565b34801561034f57600080fd5b5061022060025481565b34801561036557600080fd5b506004546102f7906001600160a01b031681565b34801561038557600080fd5b5061017061039436600461301d565b610f55565b3480156103a557600080fd5b506101926103b4366004612cf0565b60066020526000908152604090205460ff1681565b3480156103d557600080fd5b506101706103e4366004613060565b611022565b3480156103f557600080fd5b506001546001600160a01b03166102f7565b6101706104153660046130e5565b6111de565b34801561042657600080fd5b50610170610435366004612cf0565b611569565b34801561044657600080fd5b5061045a610455366004612d23565b6115da565b604080516001600160a01b03958616815294909316602085015291830152606082015260800161019e565b34801561049157600080fd5b506104a56104a0366004613277565b611690565b604080516001600160a01b0394851681529390921660208401529082015260600161019e565b6104d3611764565b6104db612b89565b6001600160a01b0388168082526040808301899052602080840192909252606083018990526101008301889052466101208401528051601f87018390048302810183019091528581529086908690819084018382808284376000920191909152505050506101408201524760055560085460408051808201909152601881527f427574746572526f7574657256323a206d6f73206f6e6c7900000000000000006020820152906001600160a01b031633146105b25760405162461bcd60e51b81526004016105a99190613320565b60405180910390fd5b50866105c28260000151306117bd565b10156040518060400160405280601f8152602001600080516020613b04833981519152815250906106065760405162461bcd60e51b81526004016105a99190613320565b5060008061061684860186613333565b9150915060008151835161062a91906133ac565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b8152509061067c5760405162461bcd60e51b81526004016105a99190613320565b506009546001906000906106919060026133bf565b84519091501561077c576000848060200190518101906106b19190613431565b60608101516001600160a01b031660a08801529050815a111561077a57306001600160a01b031663f848a5746009545a6106eb91906134fc565b8389600001518a604001516040518563ffffffff1660e01b81526004016107149392919061350f565b60606040518083038160008887f193505050508015610750575060408051601f3d908101601f1916820190925261074d918101906135ba565b60015b61075d576000925061077a565b6001600160a01b0391821660208a0152911660c088015260608701525b505b82511561087c5760008380602001905181019061079991906135fd565b60a08701519091506001600160a01b03166107c25760808101516001600160a01b031660a08701525b8280156107ce5750815a115b1561087a57306001600160a01b0316635dc4ba086009545a6107f091906134fc565b8389602001518a606001516040518563ffffffff1660e01b8152600401610819939291906136b8565b604080518083038160008887f193505050508015610854575060408051601f3d908101601f1916820190925261085191810190613729565b60015b1561087a576001600160a01b0391821660c089015260e088015260808201511660a08701525b505b8460e00151856060015111156108b2576108b285602001518660a001518760e0015188606001516108ad91906134fc565b611851565b8460c001516001600160a01b03168560a001516001600160a01b03168e7f593e4dbcb8f7312fc3bdd77e2095da131a6e1993f37752d12576d04e1f7253b4886000015189602001518a604001518b606001518c60e001518d61010001518e61012001518f610140015160405161092f989796959493929190613757565b60405180910390a450505050506109466001600755565b5050505050505050565b600061095a611889565b610963826118e3565b50600190505b919050565b6004546000908190819081906001600160a01b031661099857508592506000915081905080610a32565b60008560018111156109ac576109ac6137b0565b036109df5750506003546000906109c286611996565b6109ce57869350610a23565b6109d881886133ac565b9350610a23565b6002548692506109f290620f42406134fc565b6109ff620f4240896133bf565b610a0991906137c6565b610a149060016133ac565b9350610a2087856134fc565b90505b6004546001600160a01b031692505b93509350935093565b610a43611764565b878783838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526017815276213aba3a32b92937baba32b92b191d103d32b9379034b760491b602082015291505082610ac85760405162461bcd60e51b81526004016105a99190613320565b50805115610ad957610ad9816119cf565b610ae334476134fc565b600555610aef83611996565b15610b5257813410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d617463680000000081525090610b4c5760405162461bcd60e51b81526004016105a99190613320565b50610b5e565b610b5e83333085611a1a565b6000610b6a878a6133ac565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b81525090610bbc5760405162461bcd60e51b81526004016105a99190613320565b50610bc5612b89565b6001600160a01b038c16808252604082018c9052602082015260608082018c90528915610d33576000610bfa8b8d018d6137e8565b90506000610c118460400151856000015184611a85565b60608701526001600160a01b031660208087019190915260408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c656400000000009181019190915290915081610c7f5760405162461bcd60e51b81526004016105a99190613320565b508160a00151846060015110156040518060400160405280601f8152602001600080516020613b0483398151915281525090610cce5760405162461bcd60e51b81526004016105a99190613320565b5089158015610ce1575060008460600151115b15610d3057606082810151604051911b6bffffffffffffffffffffffff191660208201526034016040516020818303038152906040529250610d30846020015183606001518660600151611851565b50505b60008815610d76576000610d498a8c018c61381c565b8051610120860152602080820151908601516060870151919550919250610d7291339184611bf3565b9150505b82600001516001600160a01b0316336001600160a01b0316827f140fc1ae4910fc65859bbe978cf17402f862c5bd87a15aa3a0894d5aa50b0b06866020015187604001518860600151468a61012001518a604051610dd9969594939291906138cc565b60405180910390a450506000600555506109469250611882915050565b610dfe611889565b600981905560405181907ff47543a7cab136b12cca0a2ecd728c9d1943f57b923b98db48725d2b76dd4da990600090a250565b600080333014610e4057600080fd5b6000610e4d848688611d35565b60408051808201909152601f81527f427574746572526f7574657256323a2063616c6c6261636b206661696c656400602082015290935090915081610ea55760405162461bcd60e51b81526004016105a99190613320565b505093519492505050565b610eb8611889565b610ec26000611e02565b565b610ecc611889565b610ed7823383611851565b5050565b60015433906001600160a01b03168114610f495760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016105a9565b610f5281611e02565b50565b610f5d611889565b60408051808201909152601981527f427574746572526f7574657256323a207a65726f20616464720000000000000060208201526001600160a01b038416610fb85760405162461bcd60e51b81526004016105a99190613320565b50620f42408210610fc857600080fd5b600480546001600160a01b0319166001600160a01b03851690811790915560028390556003829055604051829184917f17906aa05b055ced1cea92b104912638c3ec8c90eec152fca6f36fbd8becca1d90600090a4505050565b61102a611889565b60408051808201909152601a815279427574746572526f7574657256323a206461746120656d70747960301b6020820152826110795760405162461bcd60e51b81526004016105a99190613320565b5060005b828110156111d8576110be84848381811061109a5761109a613911565b90506020020160208101906110af9190612cf0565b6001600160a01b03163b151590565b6040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e747261637400000000815250906111125760405162461bcd60e51b81526004016105a99190613320565b50816006600086868581811061112a5761112a613911565b905060200201602081019061113f9190612cf0565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905581151584848381811061117c5761117c613911565b90506020020160208101906111919190612cf0565b6001600160a01b03167f1f478f1e5aee36a892d86e821aba410dc0934cb0ebd0241dd75370833884545360405160405180910390a3806111d081613927565b91505061107d565b50505050565b6111e6611764565b888883838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526017815276213aba3a32b92937baba32b92b191d103d32b9379034b760491b60208201529150508261126b5760405162461bcd60e51b81526004016105a99190613320565b5080511561127c5761127c816119cf565b61128634476134fc565b60055561129283611996565b156112f557813410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d6174636800000000815250906112ef5760405162461bcd60e51b81526004016105a99190613320565b50611301565b61130183333085611a1a565b611309612b89565b6001600160a01b038d168152604081018c9052608081018e905261016081018b600181111561133a5761133a6137b0565b9081600181111561134d5761134d6137b0565b905250600061135c888b6133ac565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b815250906113ae5760405162461bcd60e51b81526004016105a99190613320565b506113cc816000015182604001518360800151846101600151611e1b565b606083015250604080516020601f8c018190048102820181019092528a815261144c918c908c908190840183828082843760009201919091525050604080516020601f8e018190048102820181019092528c815292508c91508b908190840183828082843760009201919091525050855160608701519092509050611feb565b60e08601819052606086018290526001600160a01b03928316602087015292821660c0860152921660a084015210156114a0576114a081602001518260a001518360e0015184606001516108ad91906134fc565b8060c001516001600160a01b03168160a001516001600160a01b0316336001600160a01b03167f54592234b1278d8a9675f22721443e0b9f8a1f4410b55bf6753330073b55e3ef846080015185600001518660200151876040015188606001518960e00151604051611546969594939291909586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b60405180910390a450506000600555505060016007555b50505050505050505050565b611571611889565b600180546001600160a01b0383166001600160a01b031990911681179091556115a26000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6004546000908190819081906001600160a01b031661160457506000925082915081905085610a32565b6000856001811115611618576116186137b0565b0361164b5760009250600354915061162f86611996565b61163a575085611679565b61164482886134fc565b9050611679565b859250620f42406002548861166091906133bf565b61166a91906137c6565b915061167682886134fc565b90505b6004546001600160a01b0316935093509350935093565b600080803330146116a057600080fd5b60006116ad858789611a85565b60408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c6564000000000060208201529195509350909150816117075760405162461bcd60e51b81526004016105a99190613320565b508660a001518210156040518060400160405280601f8152602001600080516020613b04833981519152815250906117525760405162461bcd60e51b81526004016105a99190613320565b50866020015193505093509350939050565b6002600754036117b65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105a9565b6002600755565b60006117c883611996565b156117de57506001600160a01b0381163161184b565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa158015611824573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118489190613940565b90505b92915050565b61185a83611996565b1561186e576118698282612174565b505050565b6118696001600160a01b038416838361228d565b6001600755565b6000546001600160a01b03163314610ec25760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105a9565b60006001600160a01b0382163b15156040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e747261637400000000815250906119465760405162461bcd60e51b81526004016105a99190613320565b50600880546001600160a01b0319166001600160a01b0384169081179091556040517ff43456bb773c1af890fa668fc6aabe2ea4c3141afd9e1c679f2a7d62b5a33d1790600090a2506001919050565b60006001600160a01b038216158061184b57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b600080600080600080600080888060200190518101906119ef9190613959565b97509750975097509750975097509750611a0f88888888888888886122bd565b505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526111d89085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612487565b6020808201516001600160a01b03166000908152600690915260408120548190819060ff1680611aea57507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031684602001516001600160a01b0316145b6040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420617070726f7665640000000081525090611b3e5760405162461bcd60e51b81526004016105a99190613320565b507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031684602001516001600160a01b031603611bd7576000611b8b8560c0015161255c565b90506001600160e01b03198116632e1a7d4d60e01b14801590611bbf57506001600160e01b03198116630d0e30db60e41b14155b15611bd557600086600093509350935050611bea565b505b611be2868686612577565b919450925090505b93509350939050565b6000611bfe84611996565b15611c8b57600854602083015183516040808601519051636a9a8d5560e11b81526001600160a01b039094169363d5351aaa938893611c41938c936004016139df565b60206040518083038185885af1158015611c5f573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611c849190613940565b9050611d2d565b600854611ca5906001600160a01b03868116911685612687565b600854602083015183516040808601519051632e267e4160e21b81526001600160a01b039094169363b899f90493611ce7938b938b938b929190600401613a1b565b6020604051808303816000875af1158015611d06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d2a9190613940565b90505b949350505050565b80516001600160a01b03166000908152600660209081526040808320548151808301909252601c82527f427574746572526f7574657256323a206e6f7420617070726f7665640000000092820192909252829160ff16611da85760405162461bcd60e51b81526004016105a99190613320565b50611db485858561279c565b8092508193505050600554471015604051806060016040528060268152602001613ade6026913990611df95760405162461bcd60e51b81526004016105a99190613320565b50935093915050565b600180546001600160a01b0319169055610f5281612904565b60045460009081906001600160a01b0316611e37575083611fe2565b6000836001811115611e4b57611e4b6137b0565b03611f49576003549150611e5e86611996565b15611ece5760035434116040518060400160405280601e81526020017f427574746572526f7574657256323a206c6f776572207468616e20666565000081525090611ebc5760405162461bcd60e51b81526004016105a99190613320565b50611ec782866134fc565b9050611f2d565b6003543410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d617463680000000081525090611f285760405162461bcd60e51b81526004016105a99190613320565b508490505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee9550611f74565b620f424060025486611f5b91906133bf565b611f6591906137c6565b9150611f7182866134fc565b90505b8115611fe257600454611f929087906001600160a01b031684611851565b60045460405183916001600160a01b0390811691908916907fcc4044b4bd9f077089a3cbea5f01bcacf584f45336b1b50a8fb5f5e552da5f1490611fd99089908990613a72565b60405180910390a45b94509492505050565b835160009081908490849083908190156120d85760008a8060200190518101906120159190613431565b9050612022888a83611a85565b60408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c65640000000000602082015291975095509092508261207c5760405162461bcd60e51b81526004016105a99190613320565b508060a001518410156040518060400160405280601f8152602001600080516020613b04833981519152815250906120c75760405162461bcd60e51b81526004016105a99190613320565b508060600151965080602001519550505b885115612168576000898060200190518101906120f591906135fd565b9050612102848683611d35565b60408051808201909152601f81527f427574746572526f7574657256323a2063616c6c6261636b206661696c65640060208201529094509092508261215a5760405162461bcd60e51b81526004016105a99190613320565b506080810151905190965094505b50945094509450945094565b804710156121c45760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016105a9565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612211576040519150601f19603f3d011682016040523d82523d6000602084013e612216565b606091505b50509050806118695760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016105a9565b6040516001600160a01b03831660248201526044810182905261186990849063a9059cbb60e01b90606401611a4e565b604051623f675f60e91b81526001600160a01b038881166004830152600091908a1690637ecebe0090602401602060405180830381865afa158015612306573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061232a9190613940565b60405163d505accf60e01b81526001600160a01b038a811660048301528981166024830152604482018990526064820188905260ff8716608483015260a4820186905260c48201859052919250908a169063d505accf9060e401600060405180830381600087803b15801561239e57600080fd5b505af11580156123b2573d6000803e3d6000fd5b5050604051623f675f60e91b81526001600160a01b038b81166004830152600093508c169150637ecebe0090602401602060405180830381865afa1580156123fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124229190613940565b905061242f8260016133ac565b811461155d5760405162461bcd60e51b815260206004820152602160248201527f5361666545524332303a207065726d697420646964206e6f74207375636365656044820152601960fa1b60648201526084016105a9565b60006124dc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166129549092919063ffffffff16565b90508051600014806124fd5750808060200190518101906124fd9190613aa4565b6118695760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105a9565b6000815160000361256f57506000919050565b506020015190565b608081015160009081808061258b87611996565b9050801561259b578791506125d0565b60408601516125b6906001600160a01b038916906000612687565b60408601516125d0906001600160a01b038916908a612687565b6125da84306117bd565b925085602001516001600160a01b0316828760c001516040516125fd9190613ac1565b60006040518083038185875af1925050503d806000811461263a576040519150601f19603f3d011682016040523d82523d6000602084013e61263f565b606091505b5050809550508261265085306117bd565b61265a91906134fc565b92508061267c57604086015161267c906001600160a01b038916906000612687565b505093509350939050565b8015806127015750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa1580156126db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ff9190613940565b155b61276c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016105a9565b6040516001600160a01b03831660248201526044810182905261186990849063095ea7b360e01b90606401611a4e565b6000806127a984306117bd565b604084015160a08501519192509081156127c35786828201525b6127cc86611996565b1561283b5784600001516001600160a01b031687826040516127ee9190613ac1565b60006040518083038185875af1925050503d806000811461282b576040519150601f19603f3d011682016040523d82523d6000602084013e612830565b606091505b5050809450506128e4565b861561285b57602085015161285b906001600160a01b0388169089612963565b84600001516001600160a01b031685606001518260405161287c9190613ac1565b60006040518083038185875af1925050503d80600081146128b9576040519150601f19603f3d011682016040523d82523d6000602084013e6128be565b606091505b509094505086156128e45760208501516128e4906001600160a01b038816906000612687565b6128ee86306117bd565b6128f890846134fc565b92505050935093915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060611d2d8484600085612a10565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa1580156129b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129d79190613940565b90506111d88463095ea7b360e01b856129f086866133ac565b6040516001600160a01b0390921660248301526044820152606401611a4e565b606082471015612a715760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105a9565b600080866001600160a01b03168587604051612a8d9190613ac1565b60006040518083038185875af1925050503d8060008114612aca576040519150601f19603f3d011682016040523d82523d6000602084013e612acf565b606091505b5091509150612ae087838387612aeb565b979650505050505050565b60608315612b5a578251600003612b53576001600160a01b0385163b612b535760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105a9565b5081611d2d565b611d2d8383815115612b6f5781518083602001fd5b8060405162461bcd60e51b81526004016105a99190613320565b604080516101808101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201529061016082015290565b6001600160a01b0381168114610f5257600080fd5b803561096981612bea565b60008083601f840112612c1c57600080fd5b5081356001600160401b03811115612c3357600080fd5b602083019150836020828501011115612c4b57600080fd5b9250929050565b60008060008060008060008060c0898b031215612c6e57600080fd5b883597506020890135612c8081612bea565b9650604089013595506060890135945060808901356001600160401b0380821115612caa57600080fd5b612cb68c838d01612c0a565b909650945060a08b0135915080821115612ccf57600080fd5b50612cdc8b828c01612c0a565b999c989b5096995094979396929594505050565b600060208284031215612d0257600080fd5b8135612d0d81612bea565b9392505050565b80356002811061096957600080fd5b600080600060608486031215612d3857600080fd5b833592506020840135612d4a81612bea565b9150612d5860408501612d14565b90509250925092565b60008060008060008060008060a0898b031215612d7d57600080fd5b8835612d8881612bea565b97506020890135965060408901356001600160401b0380821115612dab57600080fd5b612db78c838d01612c0a565b909850965060608b0135915080821115612dd057600080fd5b612ddc8c838d01612c0a565b909650945060808b0135915080821115612ccf57600080fd5b600060208284031215612e0757600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715612e4657612e46612e0e565b60405290565b60405160e081016001600160401b0381118282101715612e4657612e46612e0e565b604051601f8201601f191681016001600160401b0381118282101715612e9657612e96612e0e565b604052919050565b60006001600160401b03821115612eb757612eb7612e0e565b50601f01601f191660200190565b600082601f830112612ed657600080fd5b8135612ee9612ee482612e9e565b612e6e565b818152846020838601011115612efe57600080fd5b816020850160208301376000918101602001919091529392505050565b600080600060608486031215612f3057600080fd5b83356001600160401b0380821115612f4757600080fd5b9085019060c08288031215612f5b57600080fd5b612f63612e24565b8235612f6e81612bea565b81526020830135612f7e81612bea565b8060208301525060408301356040820152606083013560608201526080830135612fa781612bea565b608082015260a083013582811115612fbe57600080fd5b612fca89828601612ec5565b60a0830152509450612fe191505060208501612bff565b9150604084013590509250925092565b6000806040838503121561300457600080fd5b823561300f81612bea565b946020939093013593505050565b60008060006060848603121561303257600080fd5b833561303d81612bea565b95602085013595506040909401359392505050565b8015158114610f5257600080fd5b60008060006040848603121561307557600080fd5b83356001600160401b038082111561308c57600080fd5b818601915086601f8301126130a057600080fd5b8135818111156130af57600080fd5b8760208260051b85010111156130c457600080fd5b602092830195509350508401356130da81613052565b809150509250925092565b60008060008060008060008060008060e08b8d03121561310457600080fd5b8a35995060208b013561311681612bea565b985060408b0135975061312b60608c01612d14565b965060808b01356001600160401b038082111561314757600080fd5b6131538e838f01612c0a565b909850965060a08d013591508082111561316c57600080fd5b6131788e838f01612c0a565b909650945060c08d013591508082111561319157600080fd5b5061319e8d828e01612c0a565b915080935050809150509295989b9194979a5092959850565b60ff81168114610f5257600080fd5b8035610969816131b7565b600060e082840312156131e357600080fd5b6131eb612e4c565b90506131f6826131c6565b815261320460208301612bff565b602082015261321560408301612bff565b604082015261322660608301612bff565b606082015261323760808301612bff565b608082015260a082013560a082015260c08201356001600160401b0381111561325f57600080fd5b61326b84828501612ec5565b60c08301525092915050565b60008060006060848603121561328c57600080fd5b83356001600160401b038111156132a257600080fd5b6132ae868287016131d1565b93505060208401356132bf81612bea565b929592945050506040919091013590565b60005b838110156132eb5781810151838201526020016132d3565b50506000910152565b6000815180845261330c8160208601602086016132d0565b601f01601f19169290920160200192915050565b602081526000612d0d60208301846132f4565b6000806040838503121561334657600080fd5b82356001600160401b038082111561335d57600080fd5b61336986838701612ec5565b9350602085013591508082111561337f57600080fd5b5061338c85828601612ec5565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561184b5761184b613396565b808202811582820484141761184b5761184b613396565b8051610969816131b7565b805161096981612bea565b600082601f8301126133fd57600080fd5b815161340b612ee482612e9e565b81815284602083860101111561342057600080fd5b611d2d8260208301602087016132d0565b60006020828403121561344357600080fd5b81516001600160401b038082111561345a57600080fd5b9083019060e0828603121561346e57600080fd5b613476612e4c565b61347f836133d6565b815261348d602084016133e1565b602082015261349e604084016133e1565b60408201526134af606084016133e1565b60608201526134c0608084016133e1565b608082015260a083015160a082015260c0830151828111156134e157600080fd5b6134ed878286016133ec565b60c08301525095945050505050565b8181038181111561184b5761184b613396565b6060808252845160ff168282015260208501516001600160a01b03908116608084015260408601511660a083015284015160009061355860c08401826001600160a01b03169052565b5060808501516001600160a01b03811660e08401525060a085015161010083015260c085015160e06101208401526135946101408401826132f4565b9150506135ac60208301856001600160a01b03169052565b826040830152949350505050565b6000806000606084860312156135cf57600080fd5b83516135da81612bea565b60208501519093506135eb81612bea565b80925050604084015190509250925092565b60006020828403121561360f57600080fd5b81516001600160401b038082111561362657600080fd5b9083019060c0828603121561363a57600080fd5b613642612e24565b825161364d81612bea565b8152602083015161365d81612bea565b806020830152506040830151604082015260608301516060820152608083015161368681612bea565b608082015260a08301518281111561369d57600080fd5b6136a9878286016133ec565b60a08301525095945050505050565b60608152600060018060a01b03808651166060840152806020870151166080840152604086015160a0840152606086015160c08401528060808701511660e084015260a086015160c06101008501526137156101208501826132f4565b959091166020840152505060400152919050565b6000806040838503121561373c57600080fd5b825161374781612bea565b6020939093015192949293505050565b600061010060018060a01b03808c168452808b166020850152508860408401528760608401528660808401528560a08401528460c08401528060e08401526137a1818401856132f4565b9b9a5050505050505050505050565b634e487b7160e01b600052602160045260246000fd5b6000826137e357634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156137fa57600080fd5b81356001600160401b0381111561381057600080fd5b611d2d848285016131d1565b60006020828403121561382e57600080fd5b81356001600160401b038082111561384557600080fd5b908301906060828603121561385957600080fd5b60405160608101818110838211171561387457613874612e0e565b6040528235815260208301358281111561388d57600080fd5b61389987828601612ec5565b6020830152506040830135828111156138b157600080fd5b6138bd87828601612ec5565b60408301525095945050505050565b60018060a01b038716815285602082015284604082015283606082015282608082015260c060a0820152600061390560c08301846132f4565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161393957613939613396565b5060010190565b60006020828403121561395257600080fd5b5051919050565b600080600080600080600080610100898b03121561397657600080fd5b885161398181612bea565b60208a015190985061399281612bea565b60408a01519097506139a381612bea565b80965050606089015194506080890151935060a08901516139c3816131b7565b60c08a015160e0909a0151989b979a5095989497939692505050565b6001600160a01b0385168152608060208201819052600090613a03908301866132f4565b8460408401528281036060840152612ae081856132f4565b6001600160a01b0387811682528616602082015260c060408201819052600090613a47908301876132f4565b85606084015284608084015282810360a0840152613a6581856132f4565b9998505050505050505050565b8281526040810160028310613a9757634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b600060208284031215613ab657600080fd5b8151612d0d81613052565b60008251613ad38184602087016132d0565b919091019291505056fe427574746572526f7574657256323a206e61746976652076616c7565206f7665727370656e64427574746572526f7574657256323a207265636569766520746f6f206c6f7700a2646970667358221220bddbb247898d63d01101a703f56c97304a5f0673383c5206ab2de7759a7fa93864736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d93000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
-----Decoded View---------------
Arg [0] : _mosAddress (address): 0xfeB2b97e4Efce787c08086dC16Ab69E063911380
Arg [1] : _owner (address): 0xdf3f1Ee5BAF55055980887AaD79F6fE6e3302D93
Arg [2] : _wToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380
Arg [1] : 000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d93
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
POL | 100.00% | $0.427451 | 0.0406 | $0.017339 |
Loading...
Loading
[ Download: CSV Export ]
[ 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.