Overview
ETH Balance
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 131 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap And Bridge | 7894171 | 235 days ago | IN | 0 ETH | 0.00002854 | ||||
Swap And Bridge | 7893419 | 235 days ago | IN | 0.0007 ETH | 0.00001994 | ||||
Swap And Bridge | 7892437 | 235 days ago | IN | 0 ETH | 0.00002413 | ||||
Swap And Bridge | 7891614 | 235 days ago | IN | 0.0015 ETH | 0.00002015 | ||||
Swap And Bridge | 7890589 | 235 days ago | IN | 0.00105117 ETH | 0.00002885 | ||||
Swap And Bridge | 7885546 | 235 days ago | IN | 0.0004 ETH | 0.00004716 | ||||
Swap And Bridge | 7883814 | 235 days ago | IN | 0.001 ETH | 0.0000446 | ||||
Swap And Bridge | 7883746 | 235 days ago | IN | 0.001 ETH | 0.00004431 | ||||
Swap And Bridge | 7881518 | 235 days ago | IN | 0.0019056 ETH | 0.00002367 | ||||
Swap And Bridge | 7880689 | 236 days ago | IN | 0.01501196 ETH | 0.00003952 | ||||
Swap And Bridge | 7761626 | 240 days ago | IN | 0 ETH | 0.00003459 | ||||
Swap And Bridge | 7720737 | 241 days ago | IN | 0.00104 ETH | 0.00006044 | ||||
Swap And Bridge | 7703528 | 242 days ago | IN | 0 ETH | 0.00002703 | ||||
Swap And Bridge | 7678388 | 242 days ago | IN | 0.001 ETH | 0.0000783 | ||||
Swap And Bridge | 7676284 | 242 days ago | IN | 0.001 ETH | 0.00001522 | ||||
Swap And Bridge | 7625185 | 244 days ago | IN | 0.0003 ETH | 0.00000595 | ||||
Swap And Bridge | 7609604 | 245 days ago | IN | 0 ETH | 0.00003439 | ||||
Swap And Bridge | 7575879 | 246 days ago | IN | 0.00002 ETH | 0.00004437 | ||||
Swap And Bridge | 7528371 | 247 days ago | IN | 0.01 ETH | 0.00005646 | ||||
Swap And Bridge | 7526047 | 247 days ago | IN | 0 ETH | 0.00005704 | ||||
Swap And Bridge | 7520149 | 248 days ago | IN | 0.001 ETH | 0.00004784 | ||||
Swap And Bridge | 7518319 | 248 days ago | IN | 0.00101 ETH | 0.00002949 | ||||
Swap And Bridge | 7513463 | 248 days ago | IN | 0.001 ETH | 0.00002182 | ||||
Swap And Bridge | 7508167 | 248 days ago | IN | 0 ETH | 0.00003541 | ||||
Swap And Bridge | 7491729 | 249 days ago | IN | 0.05 ETH | 0.00002542 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
7893419 | 235 days ago | 0.0007 ETH | ||||
7892437 | 235 days ago | 0.12402834 ETH | ||||
7892437 | 235 days ago | 0.12402834 ETH | ||||
7891614 | 235 days ago | 0.0015 ETH | ||||
7890589 | 235 days ago | 0.00105117 ETH | ||||
7885546 | 235 days ago | 0.0004 ETH | ||||
7883814 | 235 days ago | 0.001 ETH | ||||
7883746 | 235 days ago | 0.001 ETH | ||||
7881518 | 235 days ago | 0.0019056 ETH | ||||
7880833 | 236 days ago | 0.01439854 ETH | ||||
7880833 | 236 days ago | 0.01439854 ETH | ||||
7880689 | 236 days ago | 0.01501196 ETH | ||||
7860146 | 236 days ago | 0.00473703 ETH | ||||
7860146 | 236 days ago | 0.00473703 ETH | ||||
7761626 | 240 days ago | 0.07645262 ETH | ||||
7761626 | 240 days ago | 0.07645262 ETH | ||||
7760259 | 240 days ago | 0.00084891 ETH | ||||
7760259 | 240 days ago | 0.00084891 ETH | ||||
7720737 | 241 days ago | 0.00104 ETH | ||||
7703528 | 242 days ago | 0.01717929 ETH | ||||
7703528 | 242 days ago | 0.01717929 ETH | ||||
7678388 | 242 days ago | 0.001 ETH | ||||
7676284 | 242 days ago | 0.001 ETH | ||||
7625185 | 244 days ago | 0.0003 ETH | ||||
7575879 | 246 days ago | 0.00002 ETH |
Loading...
Loading
Contract Name:
ButterRouterV2
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.20; 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(selfChainId, 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(selfChainId, 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(selfChainId, 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.20; 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; uint256 public immutable selfChainId = block.chainid; 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(selfChainId, _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(selfChainId, _token, msg.sender, _amount); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; 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.20; 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(uint256 _chainId, address _token, address _to, uint256 _amount) internal { if (_isNative(_token)) { Address.sendValue(payable(_to), _amount); } else { if (_chainId == 728126428 && _token == 0xa614f803B6FD780986A42c78Ec9c7f77e6DeD13C) { // Tron USDT _token.call(abi.encodeWithSelector(0xa9059cbb, _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": "london", "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
Contract ABI
API[{"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":[],"name":"selfChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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
60c06040524660a09081525062013880600955604051620040803803806200408083398101604081905262000034916200027e565b818162000041336200013d565b60408051808201909152601981527f427574746572526f7574657256323a207a65726f20616464720000000000000060208201526001600160a01b038316620000a85760405162461bcd60e51b81526004016200009f9190620002c8565b60405180910390fd5b5060408051808201909152601c81527f427574746572526f7574657256323a206e6f7420636f6e74726163740000000060208201526001600160a01b0382163b620001085760405162461bcd60e51b81526004016200009f9190620002c8565b506001600160a01b03811660805262000121826200013d565b5050600160075562000133836200015b565b5050505062000318565b600180546001600160a01b0319169055620001588162000211565b50565b60006001600160a01b0382163b15156040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e74726163740000000081525090620001c15760405162461bcd60e51b81526004016200009f9190620002c8565b50600880546001600160a01b0319166001600160a01b0384169081179091556040517ff43456bb773c1af890fa668fc6aabe2ea4c3141afd9e1c679f2a7d62b5a33d1790600090a2506001919050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146200027957600080fd5b919050565b6000806000606084860312156200029457600080fd5b6200029f8462000261565b9250620002af6020850162000261565b9150620002bf6040850162000261565b90509250925092565b600060208083528351808285015260005b81811015620002f757858101830151858201604001528201620002d9565b506000604082860101526040601f19601f8301168501019250505092915050565b60805160a051613d1862000368600039600081816103b6015281816108d001528181610d7e01528181610f5201528181611526015261211b015260008181611c4a0152611cd90152613d186000f3fe60806040526004361061014f5760003560e01c806391792d5b116100b6578063d904371e1161006f578063d904371e14610408578063e30c397814610428578063ecc847d314610446578063f2fde38b14610459578063f78f24a714610479578063f848a574146104c457600080fd5b806391792d5b14610338578063978bbdb91461034e578063b3f0067414610364578063c1b1660e14610384578063cc9e3e89146103a4578063d8b964e6146103d857600080fd5b80635dc4ba08116101085780635dc4ba0814610259578063715018a61461029857806378e3214f146102ad57806379ba5097146102cd5780638cbafe0a146102e25780638da5cb5b1461031a57600080fd5b80632344e6551461015b5780632b8b7b4b1461017d578063451559a9146101b2578063480a3411146102025780634e36b11c14610215578063536f4cfe1461023957600080fd5b3661015657005b600080fd5b34801561016757600080fd5b5061017b610176366004612e11565b61050a565b005b34801561018957600080fd5b5061019d610198366004612eaf565b6109b0565b60405190151581526020015b60405180910390f35b3480156101be57600080fd5b506101d26101cd366004612ee2565b6109ce565b6040516101a994939291909384526001600160a01b03928316602085015291166040830152606082015260800190565b61017b610210366004612f20565b610a9b565b34801561022157600080fd5b5061022b60095481565b6040519081526020016101a9565b34801561024557600080fd5b5061017b610254366004612fb4565b610e77565b34801561026557600080fd5b506102796102743660046130da565b610eb2565b604080516001600160a01b0390931683526020830191909152016101a9565b3480156102a457600080fd5b5061017b610f31565b3480156102b957600080fd5b5061017b6102c83660046131b0565b610f45565b3480156102d957600080fd5b5061017b610f7d565b3480156102ee57600080fd5b50600854610302906001600160a01b031681565b6040516001600160a01b0390911681526020016101a9565b34801561032657600080fd5b506000546001600160a01b0316610302565b34801561034457600080fd5b5061022b60035481565b34801561035a57600080fd5b5061022b60025481565b34801561037057600080fd5b50600454610302906001600160a01b031681565b34801561039057600080fd5b5061017b61039f3660046131dc565b610ff7565b3480156103b057600080fd5b5061022b7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103e457600080fd5b5061019d6103f3366004612eaf565b60066020526000908152604090205460ff1681565b34801561041457600080fd5b5061017b61042336600461321f565b6110c4565b34801561043457600080fd5b506001546001600160a01b0316610302565b61017b6104543660046132a4565b611280565b34801561046557600080fd5b5061017b610474366004612eaf565b61162c565b34801561048557600080fd5b50610499610494366004612ee2565b61169d565b604080516001600160a01b0395861681529490931660208501529183015260608201526080016101a9565b3480156104d057600080fd5b506104e46104df366004613436565b611753565b604080516001600160a01b039485168152939092166020840152908201526060016101a9565b610512611827565b61051a612d48565b6001600160a01b0388168082526040808301899052602080840192909252606083018990526101008301889052466101208401528051601f87018390048302810183019091528581529086908690819084018382808284376000920191909152505050506101408201524760055560085460408051808201909152601881527f427574746572526f7574657256323a206d6f73206f6e6c7900000000000000006020820152906001600160a01b031633146105f15760405162461bcd60e51b81526004016105e891906134df565b60405180910390fd5b5086610601826000015130611880565b10156040518060400160405280601f8152602001600080516020613cc3833981519152815250906106455760405162461bcd60e51b81526004016105e891906134df565b50600080610655848601866134f2565b91509150600081518351610669919061356b565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b815250906106bb5760405162461bcd60e51b81526004016105e891906134df565b506009546001906000906106d090600261357e565b8451909150156107bb576000848060200190518101906106f091906135f0565b60608101516001600160a01b031660a08801529050815a11156107b957306001600160a01b031663f848a5746009545a61072a91906136bb565b8389600001518a604001516040518563ffffffff1660e01b8152600401610753939291906136ce565b60606040518083038160008887f19350505050801561078f575060408051601f3d908101601f1916820190925261078c91810190613779565b60015b61079c57600092506107b9565b6001600160a01b0391821660208a0152911660c088015260608701525b505b8251156108bb576000838060200190518101906107d891906137bc565b60a08701519091506001600160a01b03166108015760808101516001600160a01b031660a08701525b82801561080d5750815a115b156108b957306001600160a01b0316635dc4ba086009545a61082f91906136bb565b8389602001518a606001516040518563ffffffff1660e01b815260040161085893929190613877565b604080518083038160008887f193505050508015610893575060408051601f3d908101601f19168201909252610890918101906138e8565b60015b156108b9576001600160a01b0391821660c089015260e088015260808201511660a08701525b505b8460e0015185606001511115610912576109127f000000000000000000000000000000000000000000000000000000000000000086602001518760a001518860e00151896060015161090d91906136bb565b611914565b8460c001516001600160a01b03168560a001516001600160a01b03168e7f593e4dbcb8f7312fc3bdd77e2095da131a6e1993f37752d12576d04e1f7253b4886000015189602001518a604001518b606001518c60e001518d61010001518e61012001518f610140015160405161098f989796959493929190613916565b60405180910390a450505050506109a66001600755565b5050505050505050565b60006109ba611a21565b6109c382611a7b565b50600190505b919050565b6004546000908190819081906001600160a01b03166109f857508592506000915081905080610a92565b6000856001811115610a0c57610a0c61396f565b03610a3f575050600354600090610a2286611b2e565b610a2e57869350610a83565b610a38818861356b565b9350610a83565b600254869250610a5290620f42406136bb565b610a5f620f42408961357e565b610a699190613985565b610a7490600161356b565b9350610a8087856136bb565b90505b6004546001600160a01b031692505b93509350935093565b610aa3611827565b878783838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526017815276213aba3a32b92937baba32b92b191d103d32b9379034b760491b602082015291505082610b285760405162461bcd60e51b81526004016105e891906134df565b50805115610b3957610b3981611b67565b610b4334476136bb565b600555610b4f83611b2e565b15610bb257813410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d617463680000000081525090610bac5760405162461bcd60e51b81526004016105e891906134df565b50610bbe565b610bbe83333085611bb2565b6000610bca878a61356b565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b81525090610c1c5760405162461bcd60e51b81526004016105e891906134df565b50610c25612d48565b6001600160a01b038c16808252604082018c9052602082015260608082018c90528915610db4576000610c5a8b8d018d6139a7565b90506000610c718460400151856000015184611c1d565b60608701526001600160a01b031660208087019190915260408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c656400000000009181019190915290915081610cdf5760405162461bcd60e51b81526004016105e891906134df565b508160a00151846060015110156040518060400160405280601f8152602001600080516020613cc383398151915281525090610d2e5760405162461bcd60e51b81526004016105e891906134df565b5089158015610d41575060008460600151115b15610db157606082810151604051911b6bffffffffffffffffffffffff191660208201526034016040516020818303038152906040529250610db17f0000000000000000000000000000000000000000000000000000000000000000856020015184606001518760600151611914565b50505b60008815610df7576000610dca8a8c018c6139db565b8051610120860152602080820151908601516060870151919550919250610df391339184611d8b565b9150505b82600001516001600160a01b0316336001600160a01b0316827f140fc1ae4910fc65859bbe978cf17402f862c5bd87a15aa3a0894d5aa50b0b06866020015187604001518860600151468a61012001518a604051610e5a96959493929190613a8b565b60405180910390a450506000600555506109a69250611a1a915050565b610e7f611a21565b600981905560405181907ff47543a7cab136b12cca0a2ecd728c9d1943f57b923b98db48725d2b76dd4da990600090a250565b600080333014610ec157600080fd5b6000610ece848688611ecd565b60408051808201909152601f81527f427574746572526f7574657256323a2063616c6c6261636b206661696c656400602082015290935090915081610f265760405162461bcd60e51b81526004016105e891906134df565b505093519492505050565b610f39611a21565b610f436000611f9a565b565b610f4d611a21565b610f797f0000000000000000000000000000000000000000000000000000000000000000833384611914565b5050565b60015433906001600160a01b03168114610feb5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016105e8565b610ff481611f9a565b50565b610fff611a21565b60408051808201909152601981527f427574746572526f7574657256323a207a65726f20616464720000000000000060208201526001600160a01b03841661105a5760405162461bcd60e51b81526004016105e891906134df565b50620f4240821061106a57600080fd5b600480546001600160a01b0319166001600160a01b03851690811790915560028390556003829055604051829184917f17906aa05b055ced1cea92b104912638c3ec8c90eec152fca6f36fbd8becca1d90600090a4505050565b6110cc611a21565b60408051808201909152601a815279427574746572526f7574657256323a206461746120656d70747960301b60208201528261111b5760405162461bcd60e51b81526004016105e891906134df565b5060005b8281101561127a5761116084848381811061113c5761113c613ad0565b90506020020160208101906111519190612eaf565b6001600160a01b03163b151590565b6040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e747261637400000000815250906111b45760405162461bcd60e51b81526004016105e891906134df565b5081600660008686858181106111cc576111cc613ad0565b90506020020160208101906111e19190612eaf565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905581151584848381811061121e5761121e613ad0565b90506020020160208101906112339190612eaf565b6001600160a01b03167f1f478f1e5aee36a892d86e821aba410dc0934cb0ebd0241dd75370833884545360405160405180910390a38061127281613ae6565b91505061111f565b50505050565b611288611827565b888883838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526017815276213aba3a32b92937baba32b92b191d103d32b9379034b760491b60208201529150508261130d5760405162461bcd60e51b81526004016105e891906134df565b5080511561131e5761131e81611b67565b61132834476136bb565b60055561133483611b2e565b1561139757813410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d6174636800000000815250906113915760405162461bcd60e51b81526004016105e891906134df565b506113a3565b6113a383333085611bb2565b6113ab612d48565b6001600160a01b038d168152604081018c9052608081018e905261016081018b60018111156113dc576113dc61396f565b908160018111156113ef576113ef61396f565b90525060006113fe888b61356b565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b815250906114505760405162461bcd60e51b81526004016105e891906134df565b5061146e816000015182604001518360800151846101600151611fb3565b606083015250604080516020601f8c018190048102820181019092528a81526114ee918c908c908190840183828082843760009201919091525050604080516020601f8e018190048102820181019092528c815292508c91508b9081908401838280828437600092019190915250508551606087015190925090506121a5565b60e08601819052606086018290526001600160a01b03928316602087015292821660c0860152921660a08401521015611563576115637f000000000000000000000000000000000000000000000000000000000000000082602001518360a001518460e00151856060015161090d91906136bb565b8060c001516001600160a01b03168160a001516001600160a01b0316336001600160a01b03167f54592234b1278d8a9675f22721443e0b9f8a1f4410b55bf6753330073b55e3ef846080015185600001518660200151876040015188606001518960e00151604051611609969594939291909586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b60405180910390a450506000600555505060016007555b50505050505050505050565b611634611a21565b600180546001600160a01b0383166001600160a01b031990911681179091556116656000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6004546000908190819081906001600160a01b03166116c757506000925082915081905085610a92565b60008560018111156116db576116db61396f565b0361170e576000925060035491506116f286611b2e565b6116fd57508561173c565b61170782886136bb565b905061173c565b859250620f424060025488611723919061357e565b61172d9190613985565b915061173982886136bb565b90505b6004546001600160a01b0316935093509350935093565b6000808033301461176357600080fd5b6000611770858789611c1d565b60408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c6564000000000060208201529195509350909150816117ca5760405162461bcd60e51b81526004016105e891906134df565b508660a001518210156040518060400160405280601f8152602001600080516020613cc3833981519152815250906118155760405162461bcd60e51b81526004016105e891906134df565b50866020015193505093509350939050565b6002600754036118795760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105e8565b6002600755565b600061188b83611b2e565b156118a157506001600160a01b0381163161190e565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa1580156118e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190b9190613aff565b90505b92915050565b61191d83611b2e565b156119315761192c828261232e565b61127a565b83632b6653dc148015611960575073a614f803b6fd780986a42c78ec9c7f77e6ded13c6001600160a01b038416145b15611a0657604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151918516916119bc9190613b18565b6000604051808303816000865af19150503d80600081146119f9576040519150601f19603f3d011682016040523d82523d6000602084013e6119fe565b606091505b50505061127a565b61127a6001600160a01b038416838361244c565b6001600755565b6000546001600160a01b03163314610f435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105e8565b60006001600160a01b0382163b15156040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e74726163740000000081525090611ade5760405162461bcd60e51b81526004016105e891906134df565b50600880546001600160a01b0319166001600160a01b0384169081179091556040517ff43456bb773c1af890fa668fc6aabe2ea4c3141afd9e1c679f2a7d62b5a33d1790600090a2506001919050565b60006001600160a01b038216158061190e57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b60008060008060008060008088806020019051810190611b879190613b34565b97509750975097509750975097509750611ba7888888888888888861247c565b505050505050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261127a9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612646565b6020808201516001600160a01b03166000908152600690915260408120548190819060ff1680611c8257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031684602001516001600160a01b0316145b6040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420617070726f7665640000000081525090611cd65760405162461bcd60e51b81526004016105e891906134df565b507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031684602001516001600160a01b031603611d6f576000611d238560c0015161271b565b90506001600160e01b03198116632e1a7d4d60e01b14801590611d5757506001600160e01b03198116630d0e30db60e41b14155b15611d6d57600086600093509350935050611d82565b505b611d7a868686612736565b919450925090505b93509350939050565b6000611d9684611b2e565b15611e2357600854602083015183516040808601519051636a9a8d5560e11b81526001600160a01b039094169363d5351aaa938893611dd9938c93600401613bba565b60206040518083038185885af1158015611df7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e1c9190613aff565b9050611ec5565b600854611e3d906001600160a01b03868116911685612846565b600854602083015183516040808601519051632e267e4160e21b81526001600160a01b039094169363b899f90493611e7f938b938b938b929190600401613bf6565b6020604051808303816000875af1158015611e9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec29190613aff565b90505b949350505050565b80516001600160a01b03166000908152600660209081526040808320548151808301909252601c82527f427574746572526f7574657256323a206e6f7420617070726f7665640000000092820192909252829160ff16611f405760405162461bcd60e51b81526004016105e891906134df565b50611f4c85858561295b565b8092508193505050600554471015604051806060016040528060268152602001613c9d6026913990611f915760405162461bcd60e51b81526004016105e891906134df565b50935093915050565b600180546001600160a01b0319169055610ff481612ac3565b60045460009081906001600160a01b0316611fcf57508361219c565b6000836001811115611fe357611fe361396f565b036120e1576003549150611ff686611b2e565b156120665760035434116040518060400160405280601e81526020017f427574746572526f7574657256323a206c6f776572207468616e206665650000815250906120545760405162461bcd60e51b81526004016105e891906134df565b5061205f82866136bb565b90506120c5565b6003543410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d6174636800000000815250906120c05760405162461bcd60e51b81526004016105e891906134df565b508490505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee955061210c565b620f4240600254866120f3919061357e565b6120fd9190613985565b915061210982866136bb565b90505b811561219c5760045461214c907f00000000000000000000000000000000000000000000000000000000000000009088906001600160a01b031685611914565b60045460405183916001600160a01b0390811691908916907fcc4044b4bd9f077089a3cbea5f01bcacf584f45336b1b50a8fb5f5e552da5f14906121939089908990613c4d565b60405180910390a45b94509492505050565b835160009081908490849083908190156122925760008a8060200190518101906121cf91906135f0565b90506121dc888a83611c1d565b60408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c6564000000000060208201529197509550909250826122365760405162461bcd60e51b81526004016105e891906134df565b508060a001518410156040518060400160405280601f8152602001600080516020613cc3833981519152815250906122815760405162461bcd60e51b81526004016105e891906134df565b508060600151965080602001519550505b885115612322576000898060200190518101906122af91906137bc565b90506122bc848683611ecd565b60408051808201909152601f81527f427574746572526f7574657256323a2063616c6c6261636b206661696c6564006020820152909450909250826123145760405162461bcd60e51b81526004016105e891906134df565b506080810151905190965094505b50945094509450945094565b8047101561237e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016105e8565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146123cb576040519150601f19603f3d011682016040523d82523d6000602084013e6123d0565b606091505b50509050806124475760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016105e8565b505050565b6040516001600160a01b03831660248201526044810182905261244790849063a9059cbb60e01b90606401611be6565b604051623f675f60e91b81526001600160a01b038881166004830152600091908a1690637ecebe0090602401602060405180830381865afa1580156124c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e99190613aff565b60405163d505accf60e01b81526001600160a01b038a811660048301528981166024830152604482018990526064820188905260ff8716608483015260a4820186905260c48201859052919250908a169063d505accf9060e401600060405180830381600087803b15801561255d57600080fd5b505af1158015612571573d6000803e3d6000fd5b5050604051623f675f60e91b81526001600160a01b038b81166004830152600093508c169150637ecebe0090602401602060405180830381865afa1580156125bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e19190613aff565b90506125ee82600161356b565b81146116205760405162461bcd60e51b815260206004820152602160248201527f5361666545524332303a207065726d697420646964206e6f74207375636365656044820152601960fa1b60648201526084016105e8565b600061269b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b139092919063ffffffff16565b90508051600014806126bc5750808060200190518101906126bc9190613c7f565b6124475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105e8565b6000815160000361272e57506000919050565b506020015190565b608081015160009081808061274a87611b2e565b9050801561275a5787915061278f565b6040860151612775906001600160a01b038916906000612846565b604086015161278f906001600160a01b038916908a612846565b6127998430611880565b925085602001516001600160a01b0316828760c001516040516127bc9190613b18565b60006040518083038185875af1925050503d80600081146127f9576040519150601f19603f3d011682016040523d82523d6000602084013e6127fe565b606091505b5050809550508261280f8530611880565b61281991906136bb565b92508061283b57604086015161283b906001600160a01b038916906000612846565b505093509350939050565b8015806128c05750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561289a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128be9190613aff565b155b61292b5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016105e8565b6040516001600160a01b03831660248201526044810182905261244790849063095ea7b360e01b90606401611be6565b6000806129688430611880565b604084015160a08501519192509081156129825786828201525b61298b86611b2e565b156129fa5784600001516001600160a01b031687826040516129ad9190613b18565b60006040518083038185875af1925050503d80600081146129ea576040519150601f19603f3d011682016040523d82523d6000602084013e6129ef565b606091505b505080945050612aa3565b8615612a1a576020850151612a1a906001600160a01b0388169089612b22565b84600001516001600160a01b0316856060015182604051612a3b9190613b18565b60006040518083038185875af1925050503d8060008114612a78576040519150601f19603f3d011682016040523d82523d6000602084013e612a7d565b606091505b50909450508615612aa3576020850151612aa3906001600160a01b038816906000612846565b612aad8630611880565b612ab790846136bb565b92505050935093915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060611ec58484600085612bcf565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612b72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b969190613aff565b905061127a8463095ea7b360e01b85612baf868661356b565b6040516001600160a01b0390921660248301526044820152606401611be6565b606082471015612c305760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105e8565b600080866001600160a01b03168587604051612c4c9190613b18565b60006040518083038185875af1925050503d8060008114612c89576040519150601f19603f3d011682016040523d82523d6000602084013e612c8e565b606091505b5091509150612c9f87838387612caa565b979650505050505050565b60608315612d19578251600003612d12576001600160a01b0385163b612d125760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105e8565b5081611ec5565b611ec58383815115612d2e5781518083602001fd5b8060405162461bcd60e51b81526004016105e891906134df565b604080516101808101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201529061016082015290565b6001600160a01b0381168114610ff457600080fd5b80356109c981612da9565b60008083601f840112612ddb57600080fd5b5081356001600160401b03811115612df257600080fd5b602083019150836020828501011115612e0a57600080fd5b9250929050565b60008060008060008060008060c0898b031215612e2d57600080fd5b883597506020890135612e3f81612da9565b9650604089013595506060890135945060808901356001600160401b0380821115612e6957600080fd5b612e758c838d01612dc9565b909650945060a08b0135915080821115612e8e57600080fd5b50612e9b8b828c01612dc9565b999c989b5096995094979396929594505050565b600060208284031215612ec157600080fd5b8135612ecc81612da9565b9392505050565b8035600281106109c957600080fd5b600080600060608486031215612ef757600080fd5b833592506020840135612f0981612da9565b9150612f1760408501612ed3565b90509250925092565b60008060008060008060008060a0898b031215612f3c57600080fd5b8835612f4781612da9565b97506020890135965060408901356001600160401b0380821115612f6a57600080fd5b612f768c838d01612dc9565b909850965060608b0135915080821115612f8f57600080fd5b612f9b8c838d01612dc9565b909650945060808b0135915080821115612e8e57600080fd5b600060208284031215612fc657600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b038111828210171561300557613005612fcd565b60405290565b60405160e081016001600160401b038111828210171561300557613005612fcd565b604051601f8201601f191681016001600160401b038111828210171561305557613055612fcd565b604052919050565b60006001600160401b0382111561307657613076612fcd565b50601f01601f191660200190565b600082601f83011261309557600080fd5b81356130a86130a38261305d565b61302d565b8181528460208386010111156130bd57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156130ef57600080fd5b83356001600160401b038082111561310657600080fd5b9085019060c0828803121561311a57600080fd5b613122612fe3565b823561312d81612da9565b8152602083013561313d81612da9565b806020830152506040830135604082015260608301356060820152608083013561316681612da9565b608082015260a08301358281111561317d57600080fd5b61318989828601613084565b60a08301525094506131a091505060208501612dbe565b9150604084013590509250925092565b600080604083850312156131c357600080fd5b82356131ce81612da9565b946020939093013593505050565b6000806000606084860312156131f157600080fd5b83356131fc81612da9565b95602085013595506040909401359392505050565b8015158114610ff457600080fd5b60008060006040848603121561323457600080fd5b83356001600160401b038082111561324b57600080fd5b818601915086601f83011261325f57600080fd5b81358181111561326e57600080fd5b8760208260051b850101111561328357600080fd5b6020928301955093505084013561329981613211565b809150509250925092565b60008060008060008060008060008060e08b8d0312156132c357600080fd5b8a35995060208b01356132d581612da9565b985060408b013597506132ea60608c01612ed3565b965060808b01356001600160401b038082111561330657600080fd5b6133128e838f01612dc9565b909850965060a08d013591508082111561332b57600080fd5b6133378e838f01612dc9565b909650945060c08d013591508082111561335057600080fd5b5061335d8d828e01612dc9565b915080935050809150509295989b9194979a5092959850565b60ff81168114610ff457600080fd5b80356109c981613376565b600060e082840312156133a257600080fd5b6133aa61300b565b90506133b582613385565b81526133c360208301612dbe565b60208201526133d460408301612dbe565b60408201526133e560608301612dbe565b60608201526133f660808301612dbe565b608082015260a082013560a082015260c08201356001600160401b0381111561341e57600080fd5b61342a84828501613084565b60c08301525092915050565b60008060006060848603121561344b57600080fd5b83356001600160401b0381111561346157600080fd5b61346d86828701613390565b935050602084013561347e81612da9565b929592945050506040919091013590565b60005b838110156134aa578181015183820152602001613492565b50506000910152565b600081518084526134cb81602086016020860161348f565b601f01601f19169290920160200192915050565b602081526000612ecc60208301846134b3565b6000806040838503121561350557600080fd5b82356001600160401b038082111561351c57600080fd5b61352886838701613084565b9350602085013591508082111561353e57600080fd5b5061354b85828601613084565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561190e5761190e613555565b808202811582820484141761190e5761190e613555565b80516109c981613376565b80516109c981612da9565b600082601f8301126135bc57600080fd5b81516135ca6130a38261305d565b8181528460208386010111156135df57600080fd5b611ec582602083016020870161348f565b60006020828403121561360257600080fd5b81516001600160401b038082111561361957600080fd5b9083019060e0828603121561362d57600080fd5b61363561300b565b61363e83613595565b815261364c602084016135a0565b602082015261365d604084016135a0565b604082015261366e606084016135a0565b606082015261367f608084016135a0565b608082015260a083015160a082015260c0830151828111156136a057600080fd5b6136ac878286016135ab565b60c08301525095945050505050565b8181038181111561190e5761190e613555565b6060808252845160ff168282015260208501516001600160a01b03908116608084015260408601511660a083015284015160009061371760c08401826001600160a01b03169052565b5060808501516001600160a01b03811660e08401525060a085015161010083015260c085015160e06101208401526137536101408401826134b3565b91505061376b60208301856001600160a01b03169052565b826040830152949350505050565b60008060006060848603121561378e57600080fd5b835161379981612da9565b60208501519093506137aa81612da9565b80925050604084015190509250925092565b6000602082840312156137ce57600080fd5b81516001600160401b03808211156137e557600080fd5b9083019060c082860312156137f957600080fd5b613801612fe3565b825161380c81612da9565b8152602083015161381c81612da9565b806020830152506040830151604082015260608301516060820152608083015161384581612da9565b608082015260a08301518281111561385c57600080fd5b613868878286016135ab565b60a08301525095945050505050565b60608152600060018060a01b03808651166060840152806020870151166080840152604086015160a0840152606086015160c08401528060808701511660e084015260a086015160c06101008501526138d46101208501826134b3565b959091166020840152505060400152919050565b600080604083850312156138fb57600080fd5b825161390681612da9565b6020939093015192949293505050565b600061010060018060a01b03808c168452808b166020850152508860408401528760608401528660808401528560a08401528460c08401528060e0840152613960818401856134b3565b9b9a5050505050505050505050565b634e487b7160e01b600052602160045260246000fd5b6000826139a257634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156139b957600080fd5b81356001600160401b038111156139cf57600080fd5b611ec584828501613390565b6000602082840312156139ed57600080fd5b81356001600160401b0380821115613a0457600080fd5b9083019060608286031215613a1857600080fd5b604051606081018181108382111715613a3357613a33612fcd565b60405282358152602083013582811115613a4c57600080fd5b613a5887828601613084565b602083015250604083013582811115613a7057600080fd5b613a7c87828601613084565b60408301525095945050505050565b60018060a01b038716815285602082015284604082015283606082015282608082015260c060a08201526000613ac460c08301846134b3565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b600060018201613af857613af8613555565b5060010190565b600060208284031215613b1157600080fd5b5051919050565b60008251613b2a81846020870161348f565b9190910192915050565b600080600080600080600080610100898b031215613b5157600080fd5b8851613b5c81612da9565b60208a0151909850613b6d81612da9565b60408a0151909750613b7e81612da9565b80965050606089015194506080890151935060a0890151613b9e81613376565b60c08a015160e0909a0151989b979a5095989497939692505050565b6001600160a01b0385168152608060208201819052600090613bde908301866134b3565b8460408401528281036060840152612c9f81856134b3565b6001600160a01b0387811682528616602082015260c060408201819052600090613c22908301876134b3565b85606084015284608084015282810360a0840152613c4081856134b3565b9998505050505050505050565b8281526040810160028310613c7257634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b600060208284031215613c9157600080fd5b8151612ecc8161321156fe427574746572526f7574657256323a206e61746976652076616c7565206f7665727370656e64427574746572526f7574657256323a207265636569766520746f6f206c6f7700a2646970667358221220118380d524e5e59daca022a7498657c63eb1760f06d20576a5e35bfb1959c7e564736f6c63430008140033000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d930000000000000000000000005300000000000000000000000000000000000004
Deployed Bytecode
0x60806040526004361061014f5760003560e01c806391792d5b116100b6578063d904371e1161006f578063d904371e14610408578063e30c397814610428578063ecc847d314610446578063f2fde38b14610459578063f78f24a714610479578063f848a574146104c457600080fd5b806391792d5b14610338578063978bbdb91461034e578063b3f0067414610364578063c1b1660e14610384578063cc9e3e89146103a4578063d8b964e6146103d857600080fd5b80635dc4ba08116101085780635dc4ba0814610259578063715018a61461029857806378e3214f146102ad57806379ba5097146102cd5780638cbafe0a146102e25780638da5cb5b1461031a57600080fd5b80632344e6551461015b5780632b8b7b4b1461017d578063451559a9146101b2578063480a3411146102025780634e36b11c14610215578063536f4cfe1461023957600080fd5b3661015657005b600080fd5b34801561016757600080fd5b5061017b610176366004612e11565b61050a565b005b34801561018957600080fd5b5061019d610198366004612eaf565b6109b0565b60405190151581526020015b60405180910390f35b3480156101be57600080fd5b506101d26101cd366004612ee2565b6109ce565b6040516101a994939291909384526001600160a01b03928316602085015291166040830152606082015260800190565b61017b610210366004612f20565b610a9b565b34801561022157600080fd5b5061022b60095481565b6040519081526020016101a9565b34801561024557600080fd5b5061017b610254366004612fb4565b610e77565b34801561026557600080fd5b506102796102743660046130da565b610eb2565b604080516001600160a01b0390931683526020830191909152016101a9565b3480156102a457600080fd5b5061017b610f31565b3480156102b957600080fd5b5061017b6102c83660046131b0565b610f45565b3480156102d957600080fd5b5061017b610f7d565b3480156102ee57600080fd5b50600854610302906001600160a01b031681565b6040516001600160a01b0390911681526020016101a9565b34801561032657600080fd5b506000546001600160a01b0316610302565b34801561034457600080fd5b5061022b60035481565b34801561035a57600080fd5b5061022b60025481565b34801561037057600080fd5b50600454610302906001600160a01b031681565b34801561039057600080fd5b5061017b61039f3660046131dc565b610ff7565b3480156103b057600080fd5b5061022b7f000000000000000000000000000000000000000000000000000000000008275081565b3480156103e457600080fd5b5061019d6103f3366004612eaf565b60066020526000908152604090205460ff1681565b34801561041457600080fd5b5061017b61042336600461321f565b6110c4565b34801561043457600080fd5b506001546001600160a01b0316610302565b61017b6104543660046132a4565b611280565b34801561046557600080fd5b5061017b610474366004612eaf565b61162c565b34801561048557600080fd5b50610499610494366004612ee2565b61169d565b604080516001600160a01b0395861681529490931660208501529183015260608201526080016101a9565b3480156104d057600080fd5b506104e46104df366004613436565b611753565b604080516001600160a01b039485168152939092166020840152908201526060016101a9565b610512611827565b61051a612d48565b6001600160a01b0388168082526040808301899052602080840192909252606083018990526101008301889052466101208401528051601f87018390048302810183019091528581529086908690819084018382808284376000920191909152505050506101408201524760055560085460408051808201909152601881527f427574746572526f7574657256323a206d6f73206f6e6c7900000000000000006020820152906001600160a01b031633146105f15760405162461bcd60e51b81526004016105e891906134df565b60405180910390fd5b5086610601826000015130611880565b10156040518060400160405280601f8152602001600080516020613cc3833981519152815250906106455760405162461bcd60e51b81526004016105e891906134df565b50600080610655848601866134f2565b91509150600081518351610669919061356b565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b815250906106bb5760405162461bcd60e51b81526004016105e891906134df565b506009546001906000906106d090600261357e565b8451909150156107bb576000848060200190518101906106f091906135f0565b60608101516001600160a01b031660a08801529050815a11156107b957306001600160a01b031663f848a5746009545a61072a91906136bb565b8389600001518a604001516040518563ffffffff1660e01b8152600401610753939291906136ce565b60606040518083038160008887f19350505050801561078f575060408051601f3d908101601f1916820190925261078c91810190613779565b60015b61079c57600092506107b9565b6001600160a01b0391821660208a0152911660c088015260608701525b505b8251156108bb576000838060200190518101906107d891906137bc565b60a08701519091506001600160a01b03166108015760808101516001600160a01b031660a08701525b82801561080d5750815a115b156108b957306001600160a01b0316635dc4ba086009545a61082f91906136bb565b8389602001518a606001516040518563ffffffff1660e01b815260040161085893929190613877565b604080518083038160008887f193505050508015610893575060408051601f3d908101601f19168201909252610890918101906138e8565b60015b156108b9576001600160a01b0391821660c089015260e088015260808201511660a08701525b505b8460e0015185606001511115610912576109127f000000000000000000000000000000000000000000000000000000000008275086602001518760a001518860e00151896060015161090d91906136bb565b611914565b8460c001516001600160a01b03168560a001516001600160a01b03168e7f593e4dbcb8f7312fc3bdd77e2095da131a6e1993f37752d12576d04e1f7253b4886000015189602001518a604001518b606001518c60e001518d61010001518e61012001518f610140015160405161098f989796959493929190613916565b60405180910390a450505050506109a66001600755565b5050505050505050565b60006109ba611a21565b6109c382611a7b565b50600190505b919050565b6004546000908190819081906001600160a01b03166109f857508592506000915081905080610a92565b6000856001811115610a0c57610a0c61396f565b03610a3f575050600354600090610a2286611b2e565b610a2e57869350610a83565b610a38818861356b565b9350610a83565b600254869250610a5290620f42406136bb565b610a5f620f42408961357e565b610a699190613985565b610a7490600161356b565b9350610a8087856136bb565b90505b6004546001600160a01b031692505b93509350935093565b610aa3611827565b878783838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526017815276213aba3a32b92937baba32b92b191d103d32b9379034b760491b602082015291505082610b285760405162461bcd60e51b81526004016105e891906134df565b50805115610b3957610b3981611b67565b610b4334476136bb565b600555610b4f83611b2e565b15610bb257813410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d617463680000000081525090610bac5760405162461bcd60e51b81526004016105e891906134df565b50610bbe565b610bbe83333085611bb2565b6000610bca878a61356b565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b81525090610c1c5760405162461bcd60e51b81526004016105e891906134df565b50610c25612d48565b6001600160a01b038c16808252604082018c9052602082015260608082018c90528915610db4576000610c5a8b8d018d6139a7565b90506000610c718460400151856000015184611c1d565b60608701526001600160a01b031660208087019190915260408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c656400000000009181019190915290915081610cdf5760405162461bcd60e51b81526004016105e891906134df565b508160a00151846060015110156040518060400160405280601f8152602001600080516020613cc383398151915281525090610d2e5760405162461bcd60e51b81526004016105e891906134df565b5089158015610d41575060008460600151115b15610db157606082810151604051911b6bffffffffffffffffffffffff191660208201526034016040516020818303038152906040529250610db17f0000000000000000000000000000000000000000000000000000000000082750856020015184606001518760600151611914565b50505b60008815610df7576000610dca8a8c018c6139db565b8051610120860152602080820151908601516060870151919550919250610df391339184611d8b565b9150505b82600001516001600160a01b0316336001600160a01b0316827f140fc1ae4910fc65859bbe978cf17402f862c5bd87a15aa3a0894d5aa50b0b06866020015187604001518860600151468a61012001518a604051610e5a96959493929190613a8b565b60405180910390a450506000600555506109a69250611a1a915050565b610e7f611a21565b600981905560405181907ff47543a7cab136b12cca0a2ecd728c9d1943f57b923b98db48725d2b76dd4da990600090a250565b600080333014610ec157600080fd5b6000610ece848688611ecd565b60408051808201909152601f81527f427574746572526f7574657256323a2063616c6c6261636b206661696c656400602082015290935090915081610f265760405162461bcd60e51b81526004016105e891906134df565b505093519492505050565b610f39611a21565b610f436000611f9a565b565b610f4d611a21565b610f797f0000000000000000000000000000000000000000000000000000000000082750833384611914565b5050565b60015433906001600160a01b03168114610feb5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084016105e8565b610ff481611f9a565b50565b610fff611a21565b60408051808201909152601981527f427574746572526f7574657256323a207a65726f20616464720000000000000060208201526001600160a01b03841661105a5760405162461bcd60e51b81526004016105e891906134df565b50620f4240821061106a57600080fd5b600480546001600160a01b0319166001600160a01b03851690811790915560028390556003829055604051829184917f17906aa05b055ced1cea92b104912638c3ec8c90eec152fca6f36fbd8becca1d90600090a4505050565b6110cc611a21565b60408051808201909152601a815279427574746572526f7574657256323a206461746120656d70747960301b60208201528261111b5760405162461bcd60e51b81526004016105e891906134df565b5060005b8281101561127a5761116084848381811061113c5761113c613ad0565b90506020020160208101906111519190612eaf565b6001600160a01b03163b151590565b6040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e747261637400000000815250906111b45760405162461bcd60e51b81526004016105e891906134df565b5081600660008686858181106111cc576111cc613ad0565b90506020020160208101906111e19190612eaf565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905581151584848381811061121e5761121e613ad0565b90506020020160208101906112339190612eaf565b6001600160a01b03167f1f478f1e5aee36a892d86e821aba410dc0934cb0ebd0241dd75370833884545360405160405180910390a38061127281613ae6565b91505061111f565b50505050565b611288611827565b888883838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526017815276213aba3a32b92937baba32b92b191d103d32b9379034b760491b60208201529150508261130d5760405162461bcd60e51b81526004016105e891906134df565b5080511561131e5761131e81611b67565b61132834476136bb565b60055561133483611b2e565b1561139757813410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d6174636800000000815250906113915760405162461bcd60e51b81526004016105e891906134df565b506113a3565b6113a383333085611bb2565b6113ab612d48565b6001600160a01b038d168152604081018c9052608081018e905261016081018b60018111156113dc576113dc61396f565b908160018111156113ef576113ef61396f565b90525060006113fe888b61356b565b116040518060400160405280601a815260200179427574746572526f7574657256323a206461746120656d70747960301b815250906114505760405162461bcd60e51b81526004016105e891906134df565b5061146e816000015182604001518360800151846101600151611fb3565b606083015250604080516020601f8c018190048102820181019092528a81526114ee918c908c908190840183828082843760009201919091525050604080516020601f8e018190048102820181019092528c815292508c91508b9081908401838280828437600092019190915250508551606087015190925090506121a5565b60e08601819052606086018290526001600160a01b03928316602087015292821660c0860152921660a08401521015611563576115637f000000000000000000000000000000000000000000000000000000000008275082602001518360a001518460e00151856060015161090d91906136bb565b8060c001516001600160a01b03168160a001516001600160a01b0316336001600160a01b03167f54592234b1278d8a9675f22721443e0b9f8a1f4410b55bf6753330073b55e3ef846080015185600001518660200151876040015188606001518960e00151604051611609969594939291909586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b60405180910390a450506000600555505060016007555b50505050505050505050565b611634611a21565b600180546001600160a01b0383166001600160a01b031990911681179091556116656000546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6004546000908190819081906001600160a01b03166116c757506000925082915081905085610a92565b60008560018111156116db576116db61396f565b0361170e576000925060035491506116f286611b2e565b6116fd57508561173c565b61170782886136bb565b905061173c565b859250620f424060025488611723919061357e565b61172d9190613985565b915061173982886136bb565b90505b6004546001600160a01b0316935093509350935093565b6000808033301461176357600080fd5b6000611770858789611c1d565b60408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c6564000000000060208201529195509350909150816117ca5760405162461bcd60e51b81526004016105e891906134df565b508660a001518210156040518060400160405280601f8152602001600080516020613cc3833981519152815250906118155760405162461bcd60e51b81526004016105e891906134df565b50866020015193505093509350939050565b6002600754036118795760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016105e8565b6002600755565b600061188b83611b2e565b156118a157506001600160a01b0381163161190e565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa1580156118e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190b9190613aff565b90505b92915050565b61191d83611b2e565b156119315761192c828261232e565b61127a565b83632b6653dc148015611960575073a614f803b6fd780986a42c78ec9c7f77e6ded13c6001600160a01b038416145b15611a0657604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151918516916119bc9190613b18565b6000604051808303816000865af19150503d80600081146119f9576040519150601f19603f3d011682016040523d82523d6000602084013e6119fe565b606091505b50505061127a565b61127a6001600160a01b038416838361244c565b6001600755565b6000546001600160a01b03163314610f435760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016105e8565b60006001600160a01b0382163b15156040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420636f6e74726163740000000081525090611ade5760405162461bcd60e51b81526004016105e891906134df565b50600880546001600160a01b0319166001600160a01b0384169081179091556040517ff43456bb773c1af890fa668fc6aabe2ea4c3141afd9e1c679f2a7d62b5a33d1790600090a2506001919050565b60006001600160a01b038216158061190e57506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b60008060008060008060008088806020019051810190611b879190613b34565b97509750975097509750975097509750611ba7888888888888888861247c565b505050505050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261127a9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612646565b6020808201516001600160a01b03166000908152600690915260408120548190819060ff1680611c8257507f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031684602001516001600160a01b0316145b6040518060400160405280601c81526020017f427574746572526f7574657256323a206e6f7420617070726f7665640000000081525090611cd65760405162461bcd60e51b81526004016105e891906134df565b507f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031684602001516001600160a01b031603611d6f576000611d238560c0015161271b565b90506001600160e01b03198116632e1a7d4d60e01b14801590611d5757506001600160e01b03198116630d0e30db60e41b14155b15611d6d57600086600093509350935050611d82565b505b611d7a868686612736565b919450925090505b93509350939050565b6000611d9684611b2e565b15611e2357600854602083015183516040808601519051636a9a8d5560e11b81526001600160a01b039094169363d5351aaa938893611dd9938c93600401613bba565b60206040518083038185885af1158015611df7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611e1c9190613aff565b9050611ec5565b600854611e3d906001600160a01b03868116911685612846565b600854602083015183516040808601519051632e267e4160e21b81526001600160a01b039094169363b899f90493611e7f938b938b938b929190600401613bf6565b6020604051808303816000875af1158015611e9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec29190613aff565b90505b949350505050565b80516001600160a01b03166000908152600660209081526040808320548151808301909252601c82527f427574746572526f7574657256323a206e6f7420617070726f7665640000000092820192909252829160ff16611f405760405162461bcd60e51b81526004016105e891906134df565b50611f4c85858561295b565b8092508193505050600554471015604051806060016040528060268152602001613c9d6026913990611f915760405162461bcd60e51b81526004016105e891906134df565b50935093915050565b600180546001600160a01b0319169055610ff481612ac3565b60045460009081906001600160a01b0316611fcf57508361219c565b6000836001811115611fe357611fe361396f565b036120e1576003549150611ff686611b2e565b156120665760035434116040518060400160405280601e81526020017f427574746572526f7574657256323a206c6f776572207468616e206665650000815250906120545760405162461bcd60e51b81526004016105e891906134df565b5061205f82866136bb565b90506120c5565b6003543410156040518060400160405280601c81526020017f427574746572526f7574657256323a20666565206d69736d6174636800000000815250906120c05760405162461bcd60e51b81526004016105e891906134df565b508490505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee955061210c565b620f4240600254866120f3919061357e565b6120fd9190613985565b915061210982866136bb565b90505b811561219c5760045461214c907f00000000000000000000000000000000000000000000000000000000000827509088906001600160a01b031685611914565b60045460405183916001600160a01b0390811691908916907fcc4044b4bd9f077089a3cbea5f01bcacf584f45336b1b50a8fb5f5e552da5f14906121939089908990613c4d565b60405180910390a45b94509492505050565b835160009081908490849083908190156122925760008a8060200190518101906121cf91906135f0565b90506121dc888a83611c1d565b60408051808201909152601b81527f427574746572526f7574657256323a2073776170206661696c6564000000000060208201529197509550909250826122365760405162461bcd60e51b81526004016105e891906134df565b508060a001518410156040518060400160405280601f8152602001600080516020613cc3833981519152815250906122815760405162461bcd60e51b81526004016105e891906134df565b508060600151965080602001519550505b885115612322576000898060200190518101906122af91906137bc565b90506122bc848683611ecd565b60408051808201909152601f81527f427574746572526f7574657256323a2063616c6c6261636b206661696c6564006020820152909450909250826123145760405162461bcd60e51b81526004016105e891906134df565b506080810151905190965094505b50945094509450945094565b8047101561237e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e636500000060448201526064016105e8565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146123cb576040519150601f19603f3d011682016040523d82523d6000602084013e6123d0565b606091505b50509050806124475760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d6179206861766520726576657274656400000000000060648201526084016105e8565b505050565b6040516001600160a01b03831660248201526044810182905261244790849063a9059cbb60e01b90606401611be6565b604051623f675f60e91b81526001600160a01b038881166004830152600091908a1690637ecebe0090602401602060405180830381865afa1580156124c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e99190613aff565b60405163d505accf60e01b81526001600160a01b038a811660048301528981166024830152604482018990526064820188905260ff8716608483015260a4820186905260c48201859052919250908a169063d505accf9060e401600060405180830381600087803b15801561255d57600080fd5b505af1158015612571573d6000803e3d6000fd5b5050604051623f675f60e91b81526001600160a01b038b81166004830152600093508c169150637ecebe0090602401602060405180830381865afa1580156125bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125e19190613aff565b90506125ee82600161356b565b81146116205760405162461bcd60e51b815260206004820152602160248201527f5361666545524332303a207065726d697420646964206e6f74207375636365656044820152601960fa1b60648201526084016105e8565b600061269b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612b139092919063ffffffff16565b90508051600014806126bc5750808060200190518101906126bc9190613c7f565b6124475760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016105e8565b6000815160000361272e57506000919050565b506020015190565b608081015160009081808061274a87611b2e565b9050801561275a5787915061278f565b6040860151612775906001600160a01b038916906000612846565b604086015161278f906001600160a01b038916908a612846565b6127998430611880565b925085602001516001600160a01b0316828760c001516040516127bc9190613b18565b60006040518083038185875af1925050503d80600081146127f9576040519150601f19603f3d011682016040523d82523d6000602084013e6127fe565b606091505b5050809550508261280f8530611880565b61281991906136bb565b92508061283b57604086015161283b906001600160a01b038916906000612846565b505093509350939050565b8015806128c05750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561289a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128be9190613aff565b155b61292b5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b60648201526084016105e8565b6040516001600160a01b03831660248201526044810182905261244790849063095ea7b360e01b90606401611be6565b6000806129688430611880565b604084015160a08501519192509081156129825786828201525b61298b86611b2e565b156129fa5784600001516001600160a01b031687826040516129ad9190613b18565b60006040518083038185875af1925050503d80600081146129ea576040519150601f19603f3d011682016040523d82523d6000602084013e6129ef565b606091505b505080945050612aa3565b8615612a1a576020850151612a1a906001600160a01b0388169089612b22565b84600001516001600160a01b0316856060015182604051612a3b9190613b18565b60006040518083038185875af1925050503d8060008114612a78576040519150601f19603f3d011682016040523d82523d6000602084013e612a7d565b606091505b50909450508615612aa3576020850151612aa3906001600160a01b038816906000612846565b612aad8630611880565b612ab790846136bb565b92505050935093915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060611ec58484600085612bcf565b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612b72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b969190613aff565b905061127a8463095ea7b360e01b85612baf868661356b565b6040516001600160a01b0390921660248301526044820152606401611be6565b606082471015612c305760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016105e8565b600080866001600160a01b03168587604051612c4c9190613b18565b60006040518083038185875af1925050503d8060008114612c89576040519150601f19603f3d011682016040523d82523d6000602084013e612c8e565b606091505b5091509150612c9f87838387612caa565b979650505050505050565b60608315612d19578251600003612d12576001600160a01b0385163b612d125760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016105e8565b5081611ec5565b611ec58383815115612d2e5781518083602001fd5b8060405162461bcd60e51b81526004016105e891906134df565b604080516101808101825260008082526020820181905291810182905260608082018390526080820183905260a0820183905260c0820183905260e08201839052610100820183905261012082018390526101408201529061016082015290565b6001600160a01b0381168114610ff457600080fd5b80356109c981612da9565b60008083601f840112612ddb57600080fd5b5081356001600160401b03811115612df257600080fd5b602083019150836020828501011115612e0a57600080fd5b9250929050565b60008060008060008060008060c0898b031215612e2d57600080fd5b883597506020890135612e3f81612da9565b9650604089013595506060890135945060808901356001600160401b0380821115612e6957600080fd5b612e758c838d01612dc9565b909650945060a08b0135915080821115612e8e57600080fd5b50612e9b8b828c01612dc9565b999c989b5096995094979396929594505050565b600060208284031215612ec157600080fd5b8135612ecc81612da9565b9392505050565b8035600281106109c957600080fd5b600080600060608486031215612ef757600080fd5b833592506020840135612f0981612da9565b9150612f1760408501612ed3565b90509250925092565b60008060008060008060008060a0898b031215612f3c57600080fd5b8835612f4781612da9565b97506020890135965060408901356001600160401b0380821115612f6a57600080fd5b612f768c838d01612dc9565b909850965060608b0135915080821115612f8f57600080fd5b612f9b8c838d01612dc9565b909650945060808b0135915080821115612e8e57600080fd5b600060208284031215612fc657600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b038111828210171561300557613005612fcd565b60405290565b60405160e081016001600160401b038111828210171561300557613005612fcd565b604051601f8201601f191681016001600160401b038111828210171561305557613055612fcd565b604052919050565b60006001600160401b0382111561307657613076612fcd565b50601f01601f191660200190565b600082601f83011261309557600080fd5b81356130a86130a38261305d565b61302d565b8181528460208386010111156130bd57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156130ef57600080fd5b83356001600160401b038082111561310657600080fd5b9085019060c0828803121561311a57600080fd5b613122612fe3565b823561312d81612da9565b8152602083013561313d81612da9565b806020830152506040830135604082015260608301356060820152608083013561316681612da9565b608082015260a08301358281111561317d57600080fd5b61318989828601613084565b60a08301525094506131a091505060208501612dbe565b9150604084013590509250925092565b600080604083850312156131c357600080fd5b82356131ce81612da9565b946020939093013593505050565b6000806000606084860312156131f157600080fd5b83356131fc81612da9565b95602085013595506040909401359392505050565b8015158114610ff457600080fd5b60008060006040848603121561323457600080fd5b83356001600160401b038082111561324b57600080fd5b818601915086601f83011261325f57600080fd5b81358181111561326e57600080fd5b8760208260051b850101111561328357600080fd5b6020928301955093505084013561329981613211565b809150509250925092565b60008060008060008060008060008060e08b8d0312156132c357600080fd5b8a35995060208b01356132d581612da9565b985060408b013597506132ea60608c01612ed3565b965060808b01356001600160401b038082111561330657600080fd5b6133128e838f01612dc9565b909850965060a08d013591508082111561332b57600080fd5b6133378e838f01612dc9565b909650945060c08d013591508082111561335057600080fd5b5061335d8d828e01612dc9565b915080935050809150509295989b9194979a5092959850565b60ff81168114610ff457600080fd5b80356109c981613376565b600060e082840312156133a257600080fd5b6133aa61300b565b90506133b582613385565b81526133c360208301612dbe565b60208201526133d460408301612dbe565b60408201526133e560608301612dbe565b60608201526133f660808301612dbe565b608082015260a082013560a082015260c08201356001600160401b0381111561341e57600080fd5b61342a84828501613084565b60c08301525092915050565b60008060006060848603121561344b57600080fd5b83356001600160401b0381111561346157600080fd5b61346d86828701613390565b935050602084013561347e81612da9565b929592945050506040919091013590565b60005b838110156134aa578181015183820152602001613492565b50506000910152565b600081518084526134cb81602086016020860161348f565b601f01601f19169290920160200192915050565b602081526000612ecc60208301846134b3565b6000806040838503121561350557600080fd5b82356001600160401b038082111561351c57600080fd5b61352886838701613084565b9350602085013591508082111561353e57600080fd5b5061354b85828601613084565b9150509250929050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561190e5761190e613555565b808202811582820484141761190e5761190e613555565b80516109c981613376565b80516109c981612da9565b600082601f8301126135bc57600080fd5b81516135ca6130a38261305d565b8181528460208386010111156135df57600080fd5b611ec582602083016020870161348f565b60006020828403121561360257600080fd5b81516001600160401b038082111561361957600080fd5b9083019060e0828603121561362d57600080fd5b61363561300b565b61363e83613595565b815261364c602084016135a0565b602082015261365d604084016135a0565b604082015261366e606084016135a0565b606082015261367f608084016135a0565b608082015260a083015160a082015260c0830151828111156136a057600080fd5b6136ac878286016135ab565b60c08301525095945050505050565b8181038181111561190e5761190e613555565b6060808252845160ff168282015260208501516001600160a01b03908116608084015260408601511660a083015284015160009061371760c08401826001600160a01b03169052565b5060808501516001600160a01b03811660e08401525060a085015161010083015260c085015160e06101208401526137536101408401826134b3565b91505061376b60208301856001600160a01b03169052565b826040830152949350505050565b60008060006060848603121561378e57600080fd5b835161379981612da9565b60208501519093506137aa81612da9565b80925050604084015190509250925092565b6000602082840312156137ce57600080fd5b81516001600160401b03808211156137e557600080fd5b9083019060c082860312156137f957600080fd5b613801612fe3565b825161380c81612da9565b8152602083015161381c81612da9565b806020830152506040830151604082015260608301516060820152608083015161384581612da9565b608082015260a08301518281111561385c57600080fd5b613868878286016135ab565b60a08301525095945050505050565b60608152600060018060a01b03808651166060840152806020870151166080840152604086015160a0840152606086015160c08401528060808701511660e084015260a086015160c06101008501526138d46101208501826134b3565b959091166020840152505060400152919050565b600080604083850312156138fb57600080fd5b825161390681612da9565b6020939093015192949293505050565b600061010060018060a01b03808c168452808b166020850152508860408401528760608401528660808401528560a08401528460c08401528060e0840152613960818401856134b3565b9b9a5050505050505050505050565b634e487b7160e01b600052602160045260246000fd5b6000826139a257634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156139b957600080fd5b81356001600160401b038111156139cf57600080fd5b611ec584828501613390565b6000602082840312156139ed57600080fd5b81356001600160401b0380821115613a0457600080fd5b9083019060608286031215613a1857600080fd5b604051606081018181108382111715613a3357613a33612fcd565b60405282358152602083013582811115613a4c57600080fd5b613a5887828601613084565b602083015250604083013582811115613a7057600080fd5b613a7c87828601613084565b60408301525095945050505050565b60018060a01b038716815285602082015284604082015283606082015282608082015260c060a08201526000613ac460c08301846134b3565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b600060018201613af857613af8613555565b5060010190565b600060208284031215613b1157600080fd5b5051919050565b60008251613b2a81846020870161348f565b9190910192915050565b600080600080600080600080610100898b031215613b5157600080fd5b8851613b5c81612da9565b60208a0151909850613b6d81612da9565b60408a0151909750613b7e81612da9565b80965050606089015194506080890151935060a0890151613b9e81613376565b60c08a015160e0909a0151989b979a5095989497939692505050565b6001600160a01b0385168152608060208201819052600090613bde908301866134b3565b8460408401528281036060840152612c9f81856134b3565b6001600160a01b0387811682528616602082015260c060408201819052600090613c22908301876134b3565b85606084015284608084015282810360a0840152613c4081856134b3565b9998505050505050505050565b8281526040810160028310613c7257634e487b7160e01b600052602160045260246000fd5b8260208301529392505050565b600060208284031215613c9157600080fd5b8151612ecc8161321156fe427574746572526f7574657256323a206e61746976652076616c7565206f7665727370656e64427574746572526f7574657256323a207265636569766520746f6f206c6f7700a2646970667358221220118380d524e5e59daca022a7498657c63eb1760f06d20576a5e35bfb1959c7e564736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d930000000000000000000000005300000000000000000000000000000000000004
-----Decoded View---------------
Arg [0] : _mosAddress (address): 0xfeB2b97e4Efce787c08086dC16Ab69E063911380
Arg [1] : _owner (address): 0xdf3f1Ee5BAF55055980887AaD79F6fE6e3302D93
Arg [2] : _wToken (address): 0x5300000000000000000000000000000000000004
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380
Arg [1] : 000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d93
Arg [2] : 0000000000000000000000005300000000000000000000000000000000000004
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 35 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
POL | 100.00% | $0.210247 | 0.0406 | $0.008528 |
Loading...
Loading
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.