More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 617 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap And Bridge | 21684209 | 9 hrs ago | IN | 40 ETH | 0.00108602 | ||||
Swap And Call | 21680857 | 20 hrs ago | IN | 0.00000144 ETH | 0.00576372 | ||||
Swap And Bridge | 21680569 | 21 hrs ago | IN | 0 ETH | 0.00308673 | ||||
Swap And Bridge | 21677590 | 31 hrs ago | IN | 0 ETH | 0.00117618 | ||||
Swap And Bridge | 21677570 | 31 hrs ago | IN | 0 ETH | 0.00126915 | ||||
Swap And Bridge | 21674553 | 41 hrs ago | IN | 0 ETH | 0.00727726 | ||||
Swap And Bridge | 21674460 | 42 hrs ago | IN | 0 ETH | 0.00335997 | ||||
Swap And Bridge | 21674432 | 42 hrs ago | IN | 0 ETH | 0.01096009 | ||||
Swap And Bridge | 21673174 | 46 hrs ago | IN | 0 ETH | 0.00237101 | ||||
Swap And Bridge | 21672111 | 2 days ago | IN | 0.022 ETH | 0.00611504 | ||||
Swap And Bridge | 21672072 | 2 days ago | IN | 0.001 ETH | 0.00228227 | ||||
Swap And Bridge | 21670528 | 2 days ago | IN | 1.75 ETH | 0.01244526 | ||||
Swap And Bridge | 21668422 | 2 days ago | IN | 0 ETH | 0.00304228 | ||||
Swap And Call | 21664940 | 3 days ago | IN | 0.00000144 ETH | 0.00818561 | ||||
Swap And Bridge | 21661720 | 3 days ago | IN | 0.5 ETH | 0.06198804 | ||||
Swap And Call | 21658985 | 3 days ago | IN | 0.00000144 ETH | 0.0096517 | ||||
Swap And Call | 21658972 | 3 days ago | IN | 0.00000144 ETH | 0.008937 | ||||
Swap And Call | 21658965 | 3 days ago | IN | 0.00000144 ETH | 0.01048339 | ||||
Swap And Call | 21658960 | 3 days ago | IN | 0.00000144 ETH | 0.01025767 | ||||
Swap And Call | 21658753 | 3 days ago | IN | 0.00000144 ETH | 0.00986732 | ||||
Swap And Call | 21658747 | 3 days ago | IN | 0.00000144 ETH | 0.0099609 | ||||
Swap And Call | 21658745 | 3 days ago | IN | 0.00000144 ETH | 0.00918392 | ||||
Swap And Call | 21658724 | 3 days ago | IN | 0.00000144 ETH | 0.00927814 | ||||
Swap And Call | 21658717 | 3 days ago | IN | 0.00000144 ETH | 0.0092951 | ||||
Swap And Call | 21658707 | 3 days ago | IN | 0.00000144 ETH | 0.00196642 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21686985 | 8 mins ago | 0.62937 ETH | ||||
21686985 | 8 mins ago | 0.62937 ETH | ||||
21686978 | 10 mins ago | 0.065934 ETH | ||||
21686978 | 10 mins ago | 0.065934 ETH | ||||
21686911 | 23 mins ago | 7.53225428 ETH | ||||
21686911 | 23 mins ago | 7.53225428 ETH | ||||
21686904 | 24 mins ago | 2.13786 ETH | ||||
21686904 | 24 mins ago | 2.13786 ETH | ||||
21686753 | 55 mins ago | 1.88781991 ETH | ||||
21686753 | 55 mins ago | 1.88781991 ETH | ||||
21686633 | 1 hr ago | 0.258741 ETH | ||||
21686633 | 1 hr ago | 0.258741 ETH | ||||
21686475 | 1 hr ago | 0.00423986 ETH | ||||
21686475 | 1 hr ago | 0.00423986 ETH | ||||
21686303 | 2 hrs ago | 3.34362577 ETH | ||||
21686303 | 2 hrs ago | 3.34362577 ETH | ||||
21685977 | 3 hrs ago | 0.00999 ETH | ||||
21685977 | 3 hrs ago | 0.00999 ETH | ||||
21685793 | 4 hrs ago | 0.02464004 ETH | ||||
21685793 | 4 hrs ago | 0.02464004 ETH | ||||
21685789 | 4 hrs ago | 0.01287011 ETH | ||||
21685789 | 4 hrs ago | 0.01287011 ETH | ||||
21685744 | 4 hrs ago | 3.24675 ETH | ||||
21685744 | 4 hrs ago | 3.24675 ETH | ||||
21685703 | 4 hrs ago | 0.0999 ETH |
Loading...
Loading
Contract Name:
ButterRouterV3
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/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/IButterBridgeV3.sol"; import "@butternetwork/bridge/contracts/interface/IButterReceiver.sol"; import "./interface/IFeeManager.sol"; import "./abstract/SwapCall.sol"; import "./interface/IButterRouterV3.sol"; import "./abstract/FeeManager.sol"; contract ButterRouterV3 is SwapCall, FeeManager, ReentrancyGuard, IButterReceiver, IButterRouterV3 { using SafeERC20 for IERC20; using Address for address; address public bridgeAddress; IFeeManager public feeManager; uint256 public gasForReFund = 80000; // use to solve deep stack struct SwapTemp { address srcToken; address swapToken; uint256 srcAmount; uint256 swapAmount; bytes32 transferId; address referrer; address initiator; address receiver; address target; uint256 callAmount; uint256 fromChain; uint256 toChain; uint256 nativeBalance; uint256 inputBalance; bytes from; } event Approve(address indexed executor, bool indexed flag); event SetFeeManager(address indexed _feeManager); event CollectFee( address indexed token, address indexed receiver, address indexed integrator, uint256 routerAmount, uint256 integratorAmount, uint256 nativeAmount, uint256 integratorNative, bytes32 transferId ); event SetBridgeAddress(address indexed _bridgeAddress); event SetGasForReFund(uint256 indexed _gasForReFund); constructor(address _bridgeAddress, address _owner, address _wToken) payable SwapCall(_wToken) FeeManager(_owner) { _setBridgeAddress(_bridgeAddress); } function setAuthorization(address[] calldata _executors, bool _flag) external onlyOwner { if (_executors.length == 0) revert Errors.EMPTY(); for (uint i = 0; i < _executors.length; i++) { if (!_executors[i].isContract()) revert Errors.NOT_CONTRACT(); approved[_executors[i]] = _flag; emit Approve(_executors[i], _flag); } } function setGasForReFund(uint256 _gasForReFund) external onlyOwner { gasForReFund = _gasForReFund; emit SetGasForReFund(_gasForReFund); } function setBridgeAddress(address _bridgeAddress) public onlyOwner returns (bool) { _setBridgeAddress(_bridgeAddress); return true; } function setWToken(address _wToken) external onlyOwner { _setWToken(_wToken); } function setFeeManager(address _feeManager) public onlyOwner { if (!_feeManager.isContract()) revert Errors.NOT_CONTRACT(); feeManager = IFeeManager(_feeManager); emit SetFeeManager(_feeManager); } function editFuncBlackList(bytes4 _func, bool _flag) external onlyOwner { _editFuncBlackList(_func, _flag); } function swapAndBridge( bytes32 _transferId, address _initiator, // initiator address address _srcToken, uint256 _amount, bytes calldata _swapData, bytes calldata _bridgeData, bytes calldata _permitData, bytes calldata _feeData ) external payable override nonReentrant returns (bytes32 orderId) { if ((_swapData.length + _bridgeData.length) == 0) revert Errors.DATA_EMPTY(); SwapTemp memory swapTemp; swapTemp.initiator = _initiator; swapTemp.srcToken = _srcToken; swapTemp.srcAmount = _amount; swapTemp.swapToken = _srcToken; swapTemp.swapAmount = _amount; swapTemp.transferId = _transferId; (swapTemp.nativeBalance, swapTemp.inputBalance) = _transferIn( swapTemp.srcToken, swapTemp.srcAmount, _permitData ); bytes memory receiver; FeeDetail memory fd; (fd, swapTemp.swapAmount, swapTemp.referrer) = _collectFee(swapTemp.srcToken, swapTemp.srcAmount, _feeData); if (_swapData.length != 0) { SwapParam memory swapParam = abi.decode(_swapData, (SwapParam)); (swapTemp.swapToken, swapTemp.swapAmount) = _swap( swapTemp.srcToken, swapTemp.swapAmount, swapTemp.inputBalance, swapParam ); if (_bridgeData.length == 0 && swapTemp.swapAmount != 0) { receiver = abi.encodePacked(swapParam.receiver); _transfer(swapTemp.swapToken, swapParam.receiver, swapTemp.swapAmount); } } 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 CollectFee( swapTemp.srcToken, fd.routerReceiver, fd.integrator, fd.routerTokenFee, fd.integratorTokenFee, fd.routerNativeFee, fd.integratorNativeFee, orderId ); emit SwapAndBridge( swapTemp.referrer, swapTemp.initiator, msg.sender, swapTemp.transferId, orderId, swapTemp.srcToken, swapTemp.swapToken, swapTemp.srcAmount, swapTemp.swapAmount, swapTemp.toChain, receiver ); _afterCheck(swapTemp.nativeBalance); } function swapAndCall( bytes32 _transferId, address _initiator, // initiator address address _srcToken, uint256 _amount, bytes calldata _swapData, bytes calldata _callbackData, bytes calldata _permitData, bytes calldata _feeData ) external payable override nonReentrant { SwapTemp memory swapTemp; swapTemp.initiator = _initiator; swapTemp.srcToken = _srcToken; swapTemp.srcAmount = _amount; swapTemp.transferId = _transferId; (swapTemp.nativeBalance, swapTemp.inputBalance) = _transferIn( swapTemp.srcToken, swapTemp.srcAmount, _permitData ); if ((_swapData.length + _callbackData.length) == 0) revert Errors.DATA_EMPTY(); FeeDetail memory fd; (fd, swapTemp.swapAmount, swapTemp.referrer) = _collectFee(swapTemp.srcToken, swapTemp.srcAmount, _feeData); emit CollectFee( swapTemp.srcToken, fd.routerReceiver, fd.integrator, fd.routerTokenFee, fd.integratorTokenFee, fd.routerNativeFee, fd.integratorNativeFee, swapTemp.transferId ); ( swapTemp.receiver, swapTemp.target, swapTemp.swapToken, swapTemp.swapAmount, swapTemp.callAmount ) = _doSwapAndCall(swapTemp.srcToken, swapTemp.swapAmount, swapTemp.inputBalance, _swapData, _callbackData); if (swapTemp.swapAmount > swapTemp.callAmount) { _transfer(swapTemp.swapToken, swapTemp.receiver, (swapTemp.swapAmount - swapTemp.callAmount)); } emit SwapAndCall( swapTemp.referrer, swapTemp.initiator, msg.sender, swapTemp.transferId, swapTemp.srcToken, swapTemp.swapToken, swapTemp.srcAmount, swapTemp.swapAmount, swapTemp.receiver, swapTemp.target, swapTemp.callAmount ); _afterCheck(swapTemp.nativeBalance); } // _srcToken must erc20 Token or wToken function onReceived( bytes32 _orderId, address _srcToken, uint256 _amount, uint256 _fromChain, bytes calldata _from, bytes calldata _swapAndCall ) external override 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; if (msg.sender != bridgeAddress) revert Errors.BRIDGE_ONLY(); { uint256 balance = _getBalance(swapTemp.srcToken, address(this)); if (balance < _amount) revert Errors.RECEIVE_LOW(); swapTemp.nativeBalance = address(this).balance; swapTemp.inputBalance = balance - _amount; } (bytes memory _swapData, bytes memory _callbackData) = abi.decode(_swapAndCall, (bytes, bytes)); if ((_swapData.length + _callbackData.length) == 0) revert Errors.DATA_EMPTY(); bool result = true; uint256 minExecGas = gasForReFund; if (_swapData.length > 0) { SwapParam memory swap = abi.decode(_swapData, (SwapParam)); swapTemp.receiver = swap.receiver; if (gasleft() > minExecGas) { try this.remoteSwap{gas: gasleft() - minExecGas}( swapTemp.srcToken, swapTemp.srcAmount, swapTemp.inputBalance, swap ) returns (address dstToken, uint256 dstAmount) { swapTemp.swapToken = dstToken; swapTemp.swapAmount = dstAmount; } catch { result = false; } } } if (_callbackData.length > 0) { CallbackParam memory callParam = abi.decode(_callbackData, (CallbackParam)); if (swapTemp.receiver == address(0)) { swapTemp.receiver = callParam.receiver; } if (result && gasleft() > minExecGas) { try this.remoteCall{gas: gasleft() - minExecGas}(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) { _transfer(swapTemp.swapToken, swapTemp.receiver, (swapTemp.swapAmount - swapTemp.callAmount)); } emit RemoteSwapAndCall( _orderId, swapTemp.receiver, swapTemp.target, swapTemp.srcToken, swapTemp.swapToken, swapTemp.srcAmount, swapTemp.swapAmount, swapTemp.callAmount, swapTemp.fromChain, swapTemp.toChain, swapTemp.from ); _afterCheck(swapTemp.nativeBalance); } function getFee( address _inputToken, uint256 _inputAmount, bytes calldata _feeData ) external view override returns (address feeToken, uint256 tokenFee, uint256 nativeFee, uint256 afterFeeAmount) { IFeeManager.FeeDetail memory fd = _getFee(_inputToken, _inputAmount, _feeData); feeToken = fd.feeToken; if (_isNative(_inputToken)) { tokenFee = 0; nativeFee = fd.routerNativeFee + fd.routerTokenFee + fd.integratorTokenFee + fd.integratorNativeFee; afterFeeAmount = _inputAmount - nativeFee; } else { tokenFee = fd.routerTokenFee + fd.integratorTokenFee; nativeFee = fd.routerNativeFee + fd.integratorNativeFee; afterFeeAmount = _inputAmount - tokenFee; } } function _getFee( address _inputToken, uint256 _inputAmount, bytes calldata _feeData ) internal view returns (FeeDetail memory fd) { if (address(feeManager) == ZERO_ADDRESS) { fd = this.getFeeDetail(_inputToken, _inputAmount, _feeData); } else { fd = feeManager.getFeeDetail(_inputToken, _inputAmount, _feeData); } } function getInputBeforeFee( address _token, uint256 _amountAfterFee, bytes calldata _feeData ) external view override returns (address _feeToken, uint256 _input, uint256 _fee) { if (address(feeManager) == ZERO_ADDRESS) { return this.getAmountBeforeFee(_token, _amountAfterFee, _feeData); } return feeManager.getAmountBeforeFee(_token, _amountAfterFee, _feeData); } function remoteSwap( address _srcToken, uint256 _amount, uint256 _initBalance, SwapParam memory swapParam ) external returns (address dstToken, uint256 dstAmount) { if (msg.sender != address(this)) revert Errors.SELF_ONLY(); (dstToken, dstAmount) = _swap(_srcToken, _amount, _initBalance, swapParam); } function remoteCall( CallbackParam memory _callbackParam, address _callToken, uint256 _amount ) external returns (address target, uint256 callAmount) { if (msg.sender != address(this)) revert Errors.SELF_ONLY(); target = _callbackParam.target; callAmount = _callBack(_amount, _callToken, _callbackParam); } function _doSwapAndCall( address _srcToken, uint256 _amount, uint256 _initBalance, bytes memory _swapData, bytes memory _callbackData ) internal returns (address receiver, address target, address dstToken, uint256 swapOutAmount, uint256 callAmount) { swapOutAmount = _amount; dstToken = _srcToken; if (_swapData.length > 0) { SwapParam memory swapParam = abi.decode(_swapData, (SwapParam)); (dstToken, swapOutAmount) = _swap(_srcToken, _amount, _initBalance, swapParam); receiver = swapParam.receiver; } if (_callbackData.length > 0) { CallbackParam memory callbackParam = abi.decode(_callbackData, (CallbackParam)); callAmount = _callBack(swapOutAmount, dstToken, callbackParam); receiver = callbackParam.receiver; target = callbackParam.target; } } function _doBridge( address _sender, address _token, uint256 _amount, BridgeParam memory _bridge ) internal returns (bytes32 _orderId) { uint256 value; address bridgeAddr = bridgeAddress; if (_isNative(_token)) { value = _amount + _bridge.nativeFee; } else { value = _bridge.nativeFee; IERC20(_token).forceApprove(bridgeAddr, _amount); } _orderId = IButterBridgeV3(bridgeAddr).swapOutToken{value: value}( _sender, _token, _bridge.receiver, _amount, _bridge.toChain, _bridge.data ); } function _collectFee( address _token, uint256 _amount, bytes calldata _feeData ) internal returns (FeeDetail memory fd, uint256 remain, address referrer) { fd = _getFee(_token, _amount, _feeData); referrer = fd.integrator; if (_isNative(_token)) { uint256 routerNative = fd.routerNativeFee + fd.routerTokenFee; if (routerNative > 0) { _transfer(_token, fd.routerReceiver, routerNative); } uint256 integratorNative = fd.integratorTokenFee + fd.integratorNativeFee; if (integratorNative > 0) { _transfer(_token, fd.integrator, integratorNative); } remain = _amount - routerNative - integratorNative; } else { if (fd.routerNativeFee > 0) { _transfer(ZERO_ADDRESS, fd.routerReceiver, fd.routerNativeFee); } if (fd.routerTokenFee > 0) { _transfer(_token, fd.routerReceiver, fd.routerTokenFee); } if (fd.integratorNativeFee > 0) { _transfer(ZERO_ADDRESS, fd.integrator, fd.integratorNativeFee); } if (fd.integratorTokenFee > 0) { _transfer(_token, fd.integrator, fd.integratorTokenFee); } remain = _amount - fd.routerTokenFee - fd.integratorTokenFee; if (fd.routerNativeFee + fd.integratorNativeFee > msg.value) revert Errors.FEE_MISMATCH(); } if (remain == 0) revert Errors.ZERO_IN(); } function _setBridgeAddress(address _bridgeAddress) internal returns (bool) { if (!_bridgeAddress.isContract()) revert Errors.NOT_CONTRACT(); bridgeAddress = _bridgeAddress; emit SetBridgeAddress(_bridgeAddress); return true; } function rescueFunds(address _token, uint256 _amount) external onlyOwner { _transfer(_token, msg.sender, _amount); } receive() external payable {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IButterBridgeV3 { struct BridgeParam { uint256 gasLimit; bytes refundAddress; bytes swapData; } function swapOutToken( address _sender, // user account send this transaction address _token, // src token bytes memory _to, // receiver account uint256 _amount, // token amount uint256 _toChain, // target chain id bytes calldata _bridgeData ) external payable returns (bytes32 orderId); function depositToken(address _token, address to, uint256 _amount) external payable; function getNativeFee(address _token, uint256 _gasLimit, uint256 _toChain) external view returns (uint256); event Relay(bytes32 orderId1, bytes32 orderId2); event CollectFee(bytes32 indexed orderId, address indexed token, uint256 value); event SwapOut( bytes32 indexed orderId, // orderId uint256 indexed tochain, // to chain address indexed token, // token to across chain uint256 amount, // amount to transfer address from, // account send this transaction address caller, // msg.sender call swapOutToken bytes to, // account receiver on target chain bytes outToken, // token bridge to target chain(token is native this maybe wtoken) uint256 gasLimit, // gasLimit for call on target chain uint256 messageFee // native amount for pass message ); event SwapIn( bytes32 indexed orderId, // orderId uint256 indexed fromChain, // from chain address indexed token, // token received on target chain uint256 amount, // target token amount address to, // account receiver on target chain address outToken, // bytes from // from chain account send this transaction ); }
// 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/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/access/Ownable2Step.sol"; import "../interface/IFeeManager.sol"; import "../interface/IButterRouterV3.sol"; import "../lib/Errors.sol"; abstract contract FeeManager is Ownable2Step, IFeeManager { uint256 constant FEE_DENOMINATOR = 10000; uint256 public routerFeeRate; uint256 public routerFixedFee; address public feeReceiver; uint256 public maxFeeRate; // referrer max fee rate uint256 public maxNativeFee; // referrer max fixed native fee event SetFee(address indexed receiver, uint256 indexed rate, uint256 indexed fixedf); event SetReferrerMaxFee(uint256 indexed _maxFeeRate, uint256 indexed _maxNativeFee); constructor(address _owner) payable { if (_owner == address(0)) revert Errors.ZERO_ADDRESS(); _transferOwnership(_owner); } function setFee(address _feeReceiver, uint256 _feeRate, uint256 _fixedFee) external onlyOwner { if (_feeReceiver == address(0)) revert Errors.ZERO_ADDRESS(); require(_feeRate < FEE_DENOMINATOR); feeReceiver = _feeReceiver; routerFeeRate = _feeRate; routerFixedFee = _fixedFee; emit SetFee(_feeReceiver, _feeRate, routerFixedFee); } function setReferrerMaxFee(uint256 _maxFeeRate, uint256 _maxNativeFee) external onlyOwner { require(_maxFeeRate < FEE_DENOMINATOR); maxFeeRate = _maxFeeRate; maxNativeFee = _maxNativeFee; emit SetReferrerMaxFee(_maxFeeRate, _maxNativeFee); } function getFeeDetail( address _inputToken, uint256 _inputAmount, bytes calldata _feeData ) external view virtual override returns (FeeDetail memory feeDetail) { IButterRouterV3.Fee memory fee = _checkFeeData(_feeData); if (feeReceiver == address(0) && fee.referrer == address(0)) { return feeDetail; } feeDetail.feeToken = _inputToken; if (feeReceiver != address(0)) { feeDetail.routerReceiver = feeReceiver; feeDetail.routerNativeFee = routerFixedFee; if (_inputToken == address(0)) { feeDetail.routerNativeFee += (_inputAmount * routerFeeRate) / FEE_DENOMINATOR; } else { feeDetail.routerTokenFee = (_inputAmount * routerFeeRate) / FEE_DENOMINATOR; } } if (fee.referrer != address(0)) { feeDetail.integrator = fee.referrer; if (fee.feeType == IButterRouterV3.FeeType.FIXED) { feeDetail.integratorNativeFee = fee.rateOrNativeFee; } else { if (_inputToken == address(0)) { feeDetail.integratorNativeFee = (_inputAmount * fee.rateOrNativeFee) / FEE_DENOMINATOR; } else { feeDetail.integratorTokenFee = (_inputAmount * fee.rateOrNativeFee) / FEE_DENOMINATOR; } } } return feeDetail; } function getAmountBeforeFee( address _token, uint256 _amountAfterFee, bytes calldata _feeData ) external view virtual returns (address feeToken, uint256 beforeAmount, uint256 nativeFeeAmount) { IButterRouterV3.Fee memory fee = _checkFeeData(_feeData); if (feeReceiver == address(0) && fee.referrer == address(0)) { return (address(0), _amountAfterFee, 0); } uint256 feeRate = 0; if (feeReceiver != address(0)) { nativeFeeAmount += routerFixedFee; feeRate += routerFeeRate; } if (fee.referrer != address(0)) { if (fee.feeType == IButterRouterV3.FeeType.FIXED) { nativeFeeAmount += fee.rateOrNativeFee; } else { feeRate += fee.rateOrNativeFee; } } if (_token == address(0) || _token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) { beforeAmount = _amountAfterFee + nativeFeeAmount; if (feeRate > 0) { beforeAmount = (beforeAmount * FEE_DENOMINATOR) / (FEE_DENOMINATOR - feeRate) + 1; } } else { if (feeRate > 0) { beforeAmount = (_amountAfterFee * FEE_DENOMINATOR) / (FEE_DENOMINATOR - feeRate) + 1; } else { beforeAmount = _amountAfterFee; } } } function _checkFeeData(bytes calldata _feeData) internal view returns (IButterRouterV3.Fee memory fee) { if (_feeData.length == 0) { return fee; } fee = abi.decode(_feeData, (IButterRouterV3.Fee)); if (fee.feeType == IButterRouterV3.FeeType.PROPORTION) { require(fee.rateOrNativeFee < maxFeeRate, "FeeManager: invalid feeRate"); } else { require(fee.rateOrNativeFee < maxNativeFee, "FeeManager: invalid native fee"); } return fee; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.20; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "../lib/Errors.sol"; abstract contract SwapCall { using SafeERC20 for IERC20; using Address for address; address internal constant ZERO_ADDRESS = address(0); address internal constant NATIVE_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public wToken; // uint256 internal nativeBalanceBeforeExec; // uint256 internal initInputTokenBalance; mapping(address => bool) public approved; mapping(bytes4 => bool) public funcBlackList; event EditFuncBlackList(bytes4 _func, bool flag); event SetWrappedToken(address indexed _wToken); enum DexType { AGG, UNIV2, UNIV3, CURVE, FILL, MIX } struct CallbackParam { address target; address approveTo; uint256 offset; uint256 extraNativeAmount; address receiver; bytes data; } struct SwapParam { address dstToken; address receiver; address leftReceiver; uint256 minAmount; SwapData[] swaps; } struct SwapData { DexType dexType; address callTo; address approveTo; uint256 fromAmount; bytes callData; } constructor(address _wToken) payable { _setWToken(_wToken); //| a9059cbb | transfer(address,uint256) funcBlackList[bytes4(0xa9059cbb)] = true; //| 095ea7b3 | approve(address,uint256) | funcBlackList[bytes4(0x095ea7b3)] = true; //| 23b872dd | transferFrom(address,address,uint256) | funcBlackList[bytes4(0x23b872dd)] = true; //| 39509351 | increaseAllowance(address,uint256) funcBlackList[bytes4(0x39509351)] = true; //| a22cb465 | setApprovalForAll(address,bool) | funcBlackList[bytes4(0xa22cb465)] = true; //| 42842e0e | safeTransferFrom(address,address,uint256) | funcBlackList[bytes4(0x42842e0e)] = true; //| b88d4fde | safeTransferFrom(address,address,uint256,bytes) | funcBlackList[bytes4(0xb88d4fde)] = true; //| 9bd9bbc6 | send(address,uint256,bytes) | funcBlackList[bytes4(0x9bd9bbc6)] = true; //| fe9d9303 | burn(uint256,bytes) | funcBlackList[bytes4(0xfe9d9303)] = true; //| 959b8c3f | authorizeOperator funcBlackList[bytes4(0x959b8c3f)] = true; //| f242432a | safeTransferFrom(address,address,uint256,uint256,bytes) | funcBlackList[bytes4(0xf242432a)] = true; //| 2eb2c2d6 | safeBatchTransferFrom(address,address,uint256[],uint256[],bytes) | funcBlackList[bytes4(0x2eb2c2d6)] = true; } function _editFuncBlackList(bytes4 _func, bool _flag) internal { funcBlackList[_func] = _flag; emit EditFuncBlackList(_func, _flag); } function _setWToken(address _wToken) internal { if (!_wToken.isContract()) revert Errors.NOT_CONTRACT(); wToken = _wToken; emit SetWrappedToken(_wToken); } function _transferIn( address token, uint256 amount, bytes memory permitData ) internal returns (uint256 nativeBalanceBeforeExec, uint256 initInputTokenBalance) { if (amount == 0) revert Errors.ZERO_IN(); if (permitData.length != 0) { _permit(permitData); } nativeBalanceBeforeExec = address(this).balance - msg.value; if (_isNative(token)) { if (msg.value < amount) revert Errors.FEE_MISMATCH(); //extra value maybe used for call native or bridge native fee initInputTokenBalance = address(this).balance - amount; } else { initInputTokenBalance = _getBalance(token, address(this)); SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount); } } function _afterCheck(uint256 nativeBalanceBeforeExec) internal view { if (address(this).balance < nativeBalanceBeforeExec) revert Errors.NATIVE_VALUE_OVERSPEND(); } function _swap( address _token, uint256 _amount, uint256 _initBalance, SwapParam memory swapParam ) internal returns (address _dstToken, uint256 _dstAmount) { _dstToken = swapParam.dstToken; if (_token == _dstToken) revert Errors.SWAP_SAME_TOKEN(); uint256 finalTokenAmount = _getBalance(swapParam.dstToken, address(this)); _doSwap(_token, _amount, swapParam); _dstAmount = _getBalance(swapParam.dstToken, address(this)) - finalTokenAmount; if (_dstAmount < swapParam.minAmount) revert Errors.RECEIVE_LOW(); uint256 left = _getBalance(_token, address(this)) - _initBalance; if (left != 0) { _transfer(_token, swapParam.leftReceiver, left); } } function _callBack( uint256 _amount, address _token, CallbackParam memory callParam ) internal returns (uint256 _callAmount) { _callAmount = _getBalance(_token, address(this)); uint256 offset = callParam.offset; bytes memory callPayload = callParam.data; if (offset > 35) { //32 length + 4 funcSig assembly { mstore(add(callPayload, offset), _amount) } } _checkApprove(callParam.target, callPayload); bool _result; if (_isNative(_token)) { (_result, ) = callParam.target.call{value: _amount}(callPayload); } 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}(callPayload); if (_amount != 0) IERC20(_token).safeApprove(callParam.approveTo, 0); } if (!_result) revert Errors.CALL_BACK_FAIL(); _callAmount = _callAmount - _getBalance(_token, address(this)); } function _checkApprove(address _callTo, bytes memory _calldata) private view { address wTokenAddr = wToken; if (_callTo != wTokenAddr && (!approved[_callTo])) revert Errors.NO_APPROVE(); bytes4 sig = _getFirst4Bytes(_calldata); if (funcBlackList[sig]) revert Errors.CALL_FUNC_BLACK_LIST(); if (_callTo == wTokenAddr) { if (sig != bytes4(0x2e1a7d4d) && sig != bytes4(0xd0e30db0)) revert Errors.CALL_FUNC_BLACK_LIST(); } } function _doSwap(address _token, uint256 _amount, SwapParam memory swapParam) internal { uint256 len = swapParam.swaps.length; if (len == 0) revert Errors.EMPTY(); (uint256 amountAdjust, uint256 firstAdjust, bool isUp) = _rebuildSwaps(_amount, len, swapParam.swaps); SwapData[] memory _swaps = swapParam.swaps; bool isNative = _isNative(_token); for (uint i = 0; i < len; ) { if (firstAdjust != 0) { if (i == 0) { isUp ? _swaps[i].fromAmount += firstAdjust : _swaps[i].fromAmount -= firstAdjust; } else { isUp ? _swaps[i].fromAmount += amountAdjust : _swaps[i].fromAmount -= amountAdjust; } } if (!isNative) { IERC20(_token).safeIncreaseAllowance(_swaps[i].approveTo, _swaps[i].fromAmount); } _execute(_swaps[i].dexType, isNative, _swaps[i].callTo, _token, _swaps[i].fromAmount, _swaps[i].callData); if (!isNative) { IERC20(_token).safeApprove(_swaps[i].approveTo, 0); } unchecked { i++; } } } function _rebuildSwaps( uint256 _amount, uint256 _len, SwapData[] memory _swaps ) private pure returns (uint256 amountAdjust, uint256 firstAdjust, bool isUp) { uint256 total = 0; for (uint256 i = 0; i < _len; i++) { total += _swaps[i].fromAmount; } if (total > _amount) { isUp = false; uint256 margin = total - _amount; amountAdjust = margin / _len; firstAdjust = amountAdjust + (margin - amountAdjust * _len); } else if (total < _amount) { isUp = true; uint256 margin = _amount - total; amountAdjust = margin / _len; firstAdjust = amountAdjust + (margin - amountAdjust * _len); } } function _execute( DexType _dexType, bool _native, address _router, address _srcToken, uint256 _amount, bytes memory _swapData ) internal { bool _result; if (_dexType == DexType.FILL) { (_result) = _makeAggFill(_router, _amount, _native, _swapData); } else if (_dexType == DexType.MIX) { (_result) = _makeMixSwap(_srcToken, _amount, _swapData); } else { revert Errors.UNSUPPORT_DEX_TYPE(); } if (!_result) revert Errors.SWAP_FAIL(); } struct MixSwap { uint256 offset; address srcToken; address callTo; address approveTo; bytes callData; } function _makeMixSwap(address _srcToken, uint256 _amount, bytes memory _swapData) internal returns (bool _result) { MixSwap[] memory mixSwaps = abi.decode(_swapData, (MixSwap[])); for (uint256 i = 0; i < mixSwaps.length; i++) { if (i != 0) { _amount = _getBalance(mixSwaps[i].srcToken, address(this)); _srcToken = mixSwaps[i].srcToken; } bytes memory callData = mixSwaps[i].callData; uint256 offset = mixSwaps[i].offset; if (offset > 35) { //32 length + 4 funcSig assembly { mstore(add(callData, offset), _amount) } } _checkApprove(mixSwaps[i].callTo, callData); if (_isNative(_srcToken)) { (_result, ) = mixSwaps[i].callTo.call{value: _amount}(callData); } else { if (i != 0) { IERC20(_srcToken).safeIncreaseAllowance(mixSwaps[i].approveTo, _amount); } (_result, ) = mixSwaps[i].callTo.call(callData); if (i != 0) { IERC20(_srcToken).safeApprove(mixSwaps[i].approveTo, 0); } } if (!_result) { break; } } } function _makeAggFill( address _router, uint256 _amount, bool native, bytes memory _swapData ) internal returns (bool _result) { (uint256[] memory offsets, bytes memory callData) = abi.decode(_swapData, (uint256[], bytes)); uint256 len = offsets.length; for (uint i = 0; i < len; i++) { uint256 offset = offsets[i]; if (offset > 35) { //32 length + 4 funcSig assembly { mstore(add(callData, offset), _amount) } } } _checkApprove(_router, callData); if (native) { (_result, ) = _router.call{value: _amount}(callData); } else { (_result, ) = _router.call(callData); } } function _isNative(address token) internal pure returns (bool) { return (token == ZERO_ADDRESS || token == NATIVE_ADDRESS); } function _getBalance(address _token, address _account) internal view returns (uint256) { if (_isNative(_token)) { return _account.balance; } else { return IERC20(_token).balanceOf(_account); } } function _transfer(address _token, address _to, uint256 _amount) internal { if (_isNative(_token)) { Address.sendValue(payable(_to), _amount); } else { uint256 _chainId = block.chainid; if (_chainId == 728126428 && _token == 0xa614f803B6FD780986A42c78Ec9c7f77e6DeD13C) { // Tron USDT _token.call(abi.encodeWithSelector(0xa9059cbb, _to, _amount)); } else { IERC20(_token).safeTransfer(_to, _amount); } } } function _getFirst4Bytes(bytes memory data) internal pure returns (bytes4 outBytes4) { if (data.length == 0) { return 0x0; } assembly { outBytes4 := mload(add(data, 32)) } } 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); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; interface IButterRouterV3 { enum FeeType { FIXED, PROPORTION } struct Fee { FeeType feeType; address referrer; uint256 rateOrNativeFee; } struct BridgeParam { uint256 toChain; uint256 nativeFee; bytes receiver; bytes data; } event SwapAndBridge( address indexed referrer, address indexed initiator, address indexed from, bytes32 transferId, bytes32 orderId, address originToken, address bridgeToken, uint256 originAmount, uint256 bridgeAmount, uint256 toChain, bytes to ); event SwapAndCall( address indexed referrer, address indexed initiator, address indexed from, bytes32 transferId, address originToken, address swapToken, uint256 originAmount, uint256 swapAmount, address receiver, address target, uint256 callAmount ); 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 ); // 1. swap: _swapData.length > 0 and _bridgeData.length == 0 // 2. swap and call: _swapData.length > 0 and _callbackData.length > 0 function swapAndCall( bytes32 _transferId, address _initiator, address _srcToken, uint256 _amount, bytes calldata _swapData, bytes calldata _callbackData, bytes calldata _permitData, bytes calldata _feeData ) external payable; // 1. bridge: _swapData.length == 0 and _bridgeData.length > 0 // 2. swap and bridge: _swapData.length > 0 and _bridgeData.length > 0 function swapAndBridge( bytes32 _transferId, address _initiator, address _srcToken, uint256 _amount, bytes calldata _swapData, bytes calldata _bridgeData, bytes calldata _permitData, bytes calldata _feeData ) external payable returns (bytes32 orderId); function getFee( address _inputToken, uint256 _inputAmount, bytes calldata _feeData ) external view returns (address feeToken, uint256 tokenFee, uint256 nativeFee, uint256 afterFeeAmount); function getInputBeforeFee( address _inputToken, uint256 _afterFeeAmount, bytes calldata _feeData ) external view returns (address feeToken, uint256 inputAmount, uint256 nativeFee); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; interface IFeeManager { struct FeeDetail { address feeToken; address routerReceiver; address integrator; uint256 routerNativeFee; uint256 integratorNativeFee; uint256 routerTokenFee; uint256 integratorTokenFee; } function getFeeDetail( address inputToken, uint256 inputAmount, bytes calldata _feeData ) external view returns (FeeDetail memory feeDetail); function getAmountBeforeFee( address inputToken, uint256 inputAmount, bytes calldata _feeData ) external view returns (address feeToken, uint256 beforeAmount, uint256 nativeFeeAmount); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.20; library Errors { error NOT_CONTRACT(); error SWAP_FAIL(); error CALL_BACK_FAIL(); error ZERO_IN(); error FEE_MISMATCH(); error FEE_LOWER(); error ZERO_ADDRESS(); error RECEIVE_LOW(); error CALL_AMOUNT_INVALID(); error BRIDGE_ONLY(); error DATA_EMPTY(); error NO_APPROVE(); error NATIVE_VALUE_OVERSPEND(); error EMPTY(); error UNSUPPORT_DEX_TYPE(); error SWAP_SAME_TOKEN(); error CANNOT_ADJUST(); error SELF_ONLY(); error CALL_FUNC_BLACK_LIST(); }
{ "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
[{"inputs":[{"internalType":"address","name":"_bridgeAddress","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_wToken","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"BRIDGE_ONLY","type":"error"},{"inputs":[],"name":"CALL_BACK_FAIL","type":"error"},{"inputs":[],"name":"CALL_FUNC_BLACK_LIST","type":"error"},{"inputs":[],"name":"DATA_EMPTY","type":"error"},{"inputs":[],"name":"EMPTY","type":"error"},{"inputs":[],"name":"FEE_MISMATCH","type":"error"},{"inputs":[],"name":"NATIVE_VALUE_OVERSPEND","type":"error"},{"inputs":[],"name":"NOT_CONTRACT","type":"error"},{"inputs":[],"name":"NO_APPROVE","type":"error"},{"inputs":[],"name":"RECEIVE_LOW","type":"error"},{"inputs":[],"name":"SELF_ONLY","type":"error"},{"inputs":[],"name":"SWAP_FAIL","type":"error"},{"inputs":[],"name":"SWAP_SAME_TOKEN","type":"error"},{"inputs":[],"name":"UNSUPPORT_DEX_TYPE","type":"error"},{"inputs":[],"name":"ZERO_ADDRESS","type":"error"},{"inputs":[],"name":"ZERO_IN","type":"error"},{"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":"address","name":"integrator","type":"address"},{"indexed":false,"internalType":"uint256","name":"routerAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"integratorAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nativeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"integratorNative","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"transferId","type":"bytes32"}],"name":"CollectFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"_func","type":"bytes4"},{"indexed":false,"internalType":"bool","name":"flag","type":"bool"}],"name":"EditFuncBlackList","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":"_bridgeAddress","type":"address"}],"name":"SetBridgeAddress","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":"address","name":"_feeManager","type":"address"}],"name":"SetFeeManager","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_gasForReFund","type":"uint256"}],"name":"SetGasForReFund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_maxFeeRate","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"_maxNativeFee","type":"uint256"}],"name":"SetReferrerMaxFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_wToken","type":"address"}],"name":"SetWrappedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":true,"internalType":"address","name":"initiator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"bytes32","name":"transferId","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"orderId","type":"bytes32"},{"indexed":false,"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":"toChain","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"to","type":"bytes"}],"name":"SwapAndBridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":true,"internalType":"address","name":"initiator","type":"address"},{"indexed":true,"internalType":"address","name":"from","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":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"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":[],"name":"bridgeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_func","type":"bytes4"},{"internalType":"bool","name":"_flag","type":"bool"}],"name":"editFuncBlackList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"contract IFeeManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"name":"funcBlackList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasForReFund","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amountAfterFee","type":"uint256"},{"internalType":"bytes","name":"_feeData","type":"bytes"}],"name":"getAmountBeforeFee","outputs":[{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"uint256","name":"beforeAmount","type":"uint256"},{"internalType":"uint256","name":"nativeFeeAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"bytes","name":"_feeData","type":"bytes"}],"name":"getFee","outputs":[{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"uint256","name":"tokenFee","type":"uint256"},{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"afterFeeAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"bytes","name":"_feeData","type":"bytes"}],"name":"getFeeDetail","outputs":[{"components":[{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"address","name":"routerReceiver","type":"address"},{"internalType":"address","name":"integrator","type":"address"},{"internalType":"uint256","name":"routerNativeFee","type":"uint256"},{"internalType":"uint256","name":"integratorNativeFee","type":"uint256"},{"internalType":"uint256","name":"routerTokenFee","type":"uint256"},{"internalType":"uint256","name":"integratorTokenFee","type":"uint256"}],"internalType":"struct IFeeManager.FeeDetail","name":"feeDetail","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amountAfterFee","type":"uint256"},{"internalType":"bytes","name":"_feeData","type":"bytes"}],"name":"getInputBeforeFee","outputs":[{"internalType":"address","name":"_feeToken","type":"address"},{"internalType":"uint256","name":"_input","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxFeeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxNativeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[{"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 SwapCall.CallbackParam","name":"_callbackParam","type":"tuple"},{"internalType":"address","name":"_callToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"remoteCall","outputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"callAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_srcToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_initBalance","type":"uint256"},{"components":[{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"leftReceiver","type":"address"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"components":[{"internalType":"enum SwapCall.DexType","name":"dexType","type":"uint8"},{"internalType":"address","name":"callTo","type":"address"},{"internalType":"address","name":"approveTo","type":"address"},{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct SwapCall.SwapData[]","name":"swaps","type":"tuple[]"}],"internalType":"struct SwapCall.SwapParam","name":"swapParam","type":"tuple"}],"name":"remoteSwap","outputs":[{"internalType":"address","name":"dstToken","type":"address"},{"internalType":"uint256","name":"dstAmount","type":"uint256"}],"stateMutability":"nonpayable","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":"routerFeeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"routerFixedFee","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":"_bridgeAddress","type":"address"}],"name":"setBridgeAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"address","name":"_feeManager","type":"address"}],"name":"setFeeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasForReFund","type":"uint256"}],"name":"setGasForReFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxFeeRate","type":"uint256"},{"internalType":"uint256","name":"_maxNativeFee","type":"uint256"}],"name":"setReferrerMaxFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wToken","type":"address"}],"name":"setWToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_transferId","type":"bytes32"},{"internalType":"address","name":"_initiator","type":"address"},{"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"},{"internalType":"bytes","name":"_feeData","type":"bytes"}],"name":"swapAndBridge","outputs":[{"internalType":"bytes32","name":"orderId","type":"bytes32"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_transferId","type":"bytes32"},{"internalType":"address","name":"_initiator","type":"address"},{"internalType":"address","name":"_srcToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_swapData","type":"bytes"},{"internalType":"bytes","name":"_callbackData","type":"bytes"},{"internalType":"bytes","name":"_permitData","type":"bytes"},{"internalType":"bytes","name":"_feeData","type":"bytes"}],"name":"swapAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405262013880600d55604051620053ab380380620053ab8339810160408190526200002d9162000418565b81816200003a81620002a0565b5060026020527fe1e73cc31923e6bcd7df033eac8d926dd327070e2255dea700a10acfabdef8c68054600160ff1991821681179092557fe35a139c3b94c056552c39ea59352e3458c2f4bf80c7cc1fa8131aa1536d11c180548216831790557f93043132120d961251ea6e8dbbd6f0f5ec18303f3dcf9ff833544e2c99ffe2ea80548216831790557fa82891a21dcbaf932ffd168b3de5be71a77172f68a75e6a28bc586fcc4c54b9f80548216831790557ff761277f7d8fd4508cc20d65fcf074f430077dd2d7ac9330f5d7f3ae6677dc1080548216831790557f063ee4a8a6581bb9c024bc06de349006da7b6941d99399873a4c8661180402dc80548216831790557fa8974dae24ddfded20eb0b277ec257b81d99ab1a9b97749cf8a0b418e0f2cf5c80548216831790557fa6afc65e3eb88af488764b72e01461c5e252915975b90bcef4390ac5030dd97180548216831790557f95e03a1175780d83ead22dfa661b326775afac6b0f1707dd3d891cf8a0ad556f80548216831790557fd1da40ac9743427d21c428e3c0e5e4496561f97a5a2cd1be0b74f92198dd93ab80548216831790557f01cb0e87ed407db17e65114eafd9fc2296f56be6b6ccc52258528879883a36c38054821683179055631759616b60e11b6000527fcdd1761221296cade29bc5e8a44093b6513834250a44de25064d79433d7cc25f80549091169091179055620002526200024c3390565b62000311565b6001600160a01b0381166200027a5760405163538ba4f960e01b815260040160405180910390fd5b620002858162000311565b506001600a5562000296836200032f565b5050505062000462565b6001600160a01b0381163b620002c9576040516308ebd80360e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f556b8b8772c1552cbcc67f9bb7c7fd60934af593e54ec7aa4e8b2683632675f891a250565b600480546001600160a01b03191690556200032c81620003a9565b50565b60006001600160a01b0382163b6200035a576040516308ebd80360e11b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0384169081179091556040517f53b7c37d01415b2804281f4684b0722e0b01fbd375bf502609f465e17ab4441e90600090a2506001919050565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200041357600080fd5b919050565b6000806000606084860312156200042e57600080fd5b6200043984620003fb565b92506200044960208501620003fb565b91506200045960408501620003fb565b90509250925092565b614f3980620004726000396000f3fe6080604052600436106101fd5760003560e01c806385c178301161010d578063c1b1660e116100a0578063d904371e1161006f578063d904371e14610678578063df5d452314610698578063e30c3978146106b8578063f2fde38b146106d6578063f5e53a64146106f657600080fd5b8063c1b1660e146105e8578063d0fb020314610608578063d7fc2da414610628578063d8b964e61461064857600080fd5b8063a3c573eb116100dc578063a3c573eb1461053e578063a73ceca71461055e578063b3f00674146105a8578063bce53d24146105c857600080fd5b806385c17830146104b55780638da5cb5b146104cb5780638dc060ff146104e95780639ccef96f146104ff57600080fd5b806352b2d5431161019057806378e3214f1161015f57806378e3214f1461039d57806379ba5097146103bd5780637ae69a98146103d25780637f5a22f914610417578063823991751461043757600080fd5b806352b2d5431461033f578063536f4cfe146103555780636e1537da14610375578063715018a61461038857600080fd5b80632344e655116101cc5780632344e655146102bb578063278fd202146102db578063472d35b9146102fb5780634e36b11c1461031b57600080fd5b80630babd86414610209578063119b82481461024657806311c4b7721461025b578063227c54121461027b57600080fd5b3661020457005b600080fd5b34801561021557600080fd5b50600054610229906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610259610254366004613b52565b61070c565b005b34801561026757600080fd5b50610259610276366004613c89565b610a7a565b34801561028757600080fd5b506102ab610296366004613cc0565b60026020526000908152604090205460ff1681565b604051901515815260200161023d565b3480156102c757600080fd5b506102596102d6366004613ce2565b610a90565b3480156102e757600080fd5b506102596102f6366004613d80565b610e7d565b34801561030757600080fd5b50610259610316366004613da2565b610ece565b34801561032757600080fd5b50610331600d5481565b60405190815260200161023d565b34801561034b57600080fd5b5061033160065481565b34801561036157600080fd5b50610259610370366004613dbf565b610f48565b610331610383366004613b52565b610f83565b34801561039457600080fd5b506102596112f3565b3480156103a957600080fd5b506102596103b8366004613dd8565b611307565b3480156103c957600080fd5b5061025961131a565b3480156103de57600080fd5b506103f26103ed366004613e04565b611399565b604080516001600160a01b03909416845260208401929092529082015260600161023d565b34801561042357600080fd5b506102ab610432366004613da2565b61151c565b34801561044357600080fd5b50610457610452366004613e04565b61153a565b6040805182516001600160a01b039081168252602080850151821690830152838301511691810191909152606080830151908201526080808301519082015260a0808301519082015260c0918201519181019190915260e00161023d565b3480156104c157600080fd5b5061033160085481565b3480156104d757600080fd5b506003546001600160a01b0316610229565b3480156104f557600080fd5b5061033160055481565b34801561050b57600080fd5b5061051f61051a366004614131565b6116bd565b604080516001600160a01b03909316835260208301919091520161023d565b34801561054a57600080fd5b50600b54610229906001600160a01b031681565b34801561056a57600080fd5b5061057e610579366004613e04565b6116f9565b604080516001600160a01b039095168552602085019390935291830152606082015260800161023d565b3480156105b457600080fd5b50600754610229906001600160a01b031681565b3480156105d457600080fd5b5061051f6105e3366004614193565b6117af565b3480156105f457600080fd5b50610259610603366004614269565b6117eb565b34801561061457600080fd5b50600c54610229906001600160a01b031681565b34801561063457600080fd5b50610259610643366004613da2565b611882565b34801561065457600080fd5b506102ab610663366004613da2565b60016020526000908152604090205460ff1681565b34801561068457600080fd5b5061025961069336600461429e565b611893565b3480156106a457600080fd5b506103f26106b3366004613e04565b6119e9565b3480156106c457600080fd5b506004546001600160a01b0316610229565b3480156106e257600080fd5b506102596106f1366004613da2565b611afc565b34801561070257600080fd5b5061033160095481565b610714611b6d565b61071c6139e3565b6001600160a01b03808d1660c08301528b1680825260408083018c9052608083018f905280516020601f880181900481028201810190925286815261077f92918d91908990899081908401838280828437600092019190915250611bc692505050565b6101a08301526101808201526107958689614339565b6000036107b5576040516312cd5ab760e11b815260040160405180910390fd5b6107bd613a92565b6107d1826000015183604001518686611c66565b846060018560a001826001600160a01b03166001600160a01b03168152508281525082935050505080604001516001600160a01b031681602001516001600160a01b031683600001516001600160a01b03167ffe2e49614659d9447156c9e3846112ea8edda361dcd696be486f6f977ce854e58460a001518560c0015186606001518760800151896080015160405161088c959493929190948552602085019390935260408401919091526060830152608082015260a00190565b60405180910390a461092882600001518360600151846101a001518d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611df792505050565b6101208701819052606087018290526001600160a01b039283166020880152928216610100870152921660e085015210156109845761098482602001518360e00151846101200151856060015161097f919061434c565b611e81565b336001600160a01b03168260c001516001600160a01b03168360a001516001600160a01b03167f60656aafa8d4c0a705aeb148b167d7db921d08852cd2261b270d5c7a2e655f83856080015186600001518760200151886040015189606001518a60e001518b61010001518c6101200151604051610a4a9897969594939291909788526001600160a01b039687166020890152948616604088015260608701939093526080860191909152831660a085015290911660c083015260e08201526101000190565b60405180910390a4610a60826101800151611f88565b5050610a6c6001600a55565b505050505050505050505050565b610a82611fa9565b610a8c8282612003565b5050565b610a98611b6d565b610aa06139e3565b6001600160a01b0388168082526040808301899052602080840192909252606083018990526101408301889052466101608401528051601f87018390048302810183019091528581529086908690819084018382808284376000920191909152505050506101c0820152600b546001600160a01b03163314610b35576040516303d6041760e41b815260040160405180910390fd5b6000610b45826000015130612067565b905087811015610b68576040516319af26f360e31b815260040160405180910390fd5b47610180830152610b79888261434c565b6101a083015250600080610b8f8486018661435f565b9150915080518251610ba19190614339565b600003610bc1576040516312cd5ab760e11b815260040160405180910390fd5b600d5482516001919015610ca557600084806020019051810190610be5919061442b565b60208101516001600160a01b031660e08801529050815a1115610ca35730639ccef96f835a610c14919061434c565b88516040808b01516101a08c015191516001600160e01b031960e087901b168152610c459392908890600401614604565b604080518083038160008887f193505050508015610c80575060408051601f3d908101601f19168201909252610c7d91810190614717565b60015b610c8d5760009250610ca3565b6001600160a01b03909116602088015260608701525b505b825115610d9c57600083806020019051810190610cc29190614745565b60e08701519091506001600160a01b0316610ceb5760808101516001600160a01b031660e08701525b828015610cf75750815a115b15610d9a573063bce53d24835a610d0e919061434c565b8389602001518a606001516040518563ffffffff1660e01b8152600401610d3793929190614800565b604080518083038160008887f193505050508015610d72575060408051601f3d908101601f19168201909252610d6f91810190614717565b60015b15610d9a576001600160a01b0391821661010089015261012088015260808201511660e08701525b505b84610120015185606001511115610dcf57610dcf85602001518660e00151876101200151886060015161097f919061434c565b8461010001516001600160a01b03168560e001516001600160a01b03168e7f593e4dbcb8f7312fc3bdd77e2095da131a6e1993f37752d12576d04e1f7253b4886000015189602001518a604001518b606001518c61012001518d61014001518e61016001518f6101c00151604051610e4e989796959493929190614871565b60405180910390a4610e64856101800151611f88565b5050505050610e736001600a55565b5050505050505050565b610e85611fa9565b6127108210610e9357600080fd5b60088290556009819055604051819083907f5b2f81a75439605ecd08ce07af893a489989a97d6d2008dff44c6827503ba82c90600090a35050565b610ed6611fa9565b6001600160a01b0381163b610efe576040516308ebd80360e11b815260040160405180910390fd5b600c80546001600160a01b0319166001600160a01b0383169081179091556040517f5d0517e3a4eabea892d9750138cd21d4a6cf3b935b43d0598df7055f463819b290600090a250565b610f50611fa9565b600d81905560405181907ff47543a7cab136b12cca0a2ecd728c9d1943f57b923b98db48725d2b76dd4da990600090a250565b6000610f8d611b6d565b610f978689614339565b600003610fb7576040516312cd5ab760e11b815260040160405180910390fd5b610fbf6139e3565b8c8160c001906001600160a01b031690816001600160a01b0316815250508b81600001906001600160a01b031690816001600160a01b0316815250508a8160400181815250508b81602001906001600160a01b031690816001600160a01b0316815250508a8160600181815250508d8160800181815250506110808160000151826040015188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bc692505050565b6101a08301526101808201526060611096613a92565b6110aa836000015184604001518888611c66565b6001600160a01b031660a0860152606085015290508a1561116c5760006110d38c8e018e6148ca565b90506110ee84600001518560600151866101a00151846120fb565b60608601526001600160a01b03166020850152891580156111125750606084015115155b1561116a57602080820151604051611142920160609190911b6bffffffffffffffffffffffff1916815260140190565b604051602081830303815290604052925061116a846020015182602001518660600151611e81565b505b88156111ad5760006111808a8c018c6148fe565b80516101608601526040810151602086015160608701519195509192506111a9913391846121c4565b9450505b80604001516001600160a01b031681602001516001600160a01b031684600001516001600160a01b03167ffe2e49614659d9447156c9e3846112ea8edda361dcd696be486f6f977ce854e58460a001518560c00151866060015187608001518b60405161123c959493929190948552602085019390935260408401919091526060830152608082015260a00190565b60405180910390a4336001600160a01b03168360c001516001600160a01b03168460a001516001600160a01b03167fba828651bf4de06e53231285961e555fd7dfe17a3e39d64b09fbaa8ebc0166c6866080015188886000015189602001518a604001518b606001518c61016001518c6040516112c09897969594939291906149a2565b60405180910390a46112d6836101800151611f88565b5050506112e36001600a55565b9c9b505050505050505050505050565b6112fb611fa9565b61130560006122a4565b565b61130f611fa9565b610a8c823383611e81565b60045433906001600160a01b0316811461138d5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b611396816122a4565b50565b6000806000806113a986866122bd565b6007549091506001600160a01b03161580156113d0575060208101516001600160a01b0316155b156113e657600087600093509350935050611512565b6007546000906001600160a01b03161561141a576006546114079084614339565b9250600554816114179190614339565b90505b60208201516001600160a01b03161561146f57600082516001811115611442576114426145c2565b0361145d5760408201516114569084614339565b925061146f565b604082015161146c9082614339565b90505b6001600160a01b03891615806114a1575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b038a16145b156114ed576114b08389614339565b935080156114e8576114c48161271061434c565b6114d0612710866149ec565b6114da9190614a03565b6114e5906001614339565b93505b61150f565b801561150b576114ff8161271061434c565b6114d06127108a6149ec565b8793505b50505b9450945094915050565b6000611526611fa9565b61152f826123b7565b50600190505b919050565b611542613a92565b600061154e84846122bd565b6007549091506001600160a01b0316158015611575575060208101516001600160a01b0316155b1561158057506116b5565b6001600160a01b038087168352600754161561160c576007546001600160a01b039081166020840152600654606084015286166115eb57612710600554866115c891906149ec565b6115d29190614a03565b826060018181516115e39190614339565b90525061160c565b612710600554866115fc91906149ec565b6116069190614a03565b60a08301525b60208101516001600160a01b0316156116b35760208101516001600160a01b03166040830152600081516001811115611647576116476145c2565b0361165b57604081015160808301526116b3565b6001600160a01b0386166116905761271081604001518661167c91906149ec565b6116869190614a03565b60808301526116b3565b6127108160400151866116a391906149ec565b6116ad9190614a03565b60c08301525b505b949350505050565b6000803330146116e057604051632ee47ea160e11b815260040160405180910390fd5b6116ec868686866120fb565b9097909650945050505050565b600080600080600061170d89898989612430565b80519550905061171c89612539565b1561176a576000935080608001518160c001518260a0015183606001516117439190614339565b61174d9190614339565b6117579190614339565b9250611763838961434c565b91506117a3565b8060c001518160a0015161177e9190614339565b9350806080015181606001516117949190614339565b92506117a0848961434c565b91505b50945094509450949050565b6000803330146117d257604051632ee47ea160e11b815260040160405180910390fd5b845191506117e1838587612572565b9050935093915050565b6117f3611fa9565b6001600160a01b03831661181a5760405163538ba4f960e01b815260040160405180910390fd5b612710821061182857600080fd5b600780546001600160a01b0319166001600160a01b03851690811790915560058390556006829055604051829184917f17906aa05b055ced1cea92b104912638c3ec8c90eec152fca6f36fbd8becca1d90600090a4505050565b61188a611fa9565b611396816126fc565b61189b611fa9565b60008290036118bd57604051630239912560e01b815260040160405180910390fd5b60005b828110156119e3576119018484838181106118dd576118dd614a25565b90506020020160208101906118f29190613da2565b6001600160a01b03163b151590565b61191e576040516308ebd80360e11b815260040160405180910390fd5b816001600086868581811061193557611935614a25565b905060200201602081019061194a9190613da2565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905581151584848381811061198757611987614a25565b905060200201602081019061199c9190613da2565b6001600160a01b03167f1f478f1e5aee36a892d86e821aba410dc0934cb0ebd0241dd75370833884545360405160405180910390a3806119db81614a3b565b9150506118c0565b50505050565b600c54600090819081906001600160a01b0316611a7557604051630f5cd35360e31b81523090637ae69a9890611a29908a908a908a908a90600401614a54565b606060405180830381865afa158015611a46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6a9190614a9c565b925092509250611512565b600c54604051630f5cd35360e31b81526001600160a01b0390911690637ae69a9890611aab908a908a908a908a90600401614a54565b606060405180830381865afa158015611ac8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aec9190614a9c565b9250925092509450945094915050565b611b04611fa9565b600480546001600160a01b0383166001600160a01b03199091168117909155611b356003546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6002600a5403611bbf5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611384565b6002600a55565b60008083600003611bea5760405163090b95c560e31b815260040160405180910390fd5b825115611bfa57611bfa8361276c565b611c04344761434c565b9150611c0f85612539565b15611c465783341015611c3557604051637d6b3cdf60e11b815260040160405180910390fd5b611c3f844761434c565b9050611c5e565b611c508530612067565b9050611c5e853330876127b7565b935093915050565b611c6e613a92565b600080611c7d87878787612430565b925082604001519050611c8f87612539565b15611d0c5760008360a001518460600151611caa9190614339565b90508015611cc157611cc188856020015183611e81565b600084608001518560c00151611cd79190614339565b90508015611cee57611cee89866040015183611e81565b80611cf9838a61434c565b611d03919061434c565b93505050611dd6565b606083015115611d2a57611d2a600084602001518560600151611e81565b60a083015115611d4757611d478784602001518560a00151611e81565b608083015115611d6557611d65600084604001518560800151611e81565b60c083015115611d8257611d828784604001518560c00151611e81565b60c083015160a0840151611d96908861434c565b611da0919061434c565b91503483608001518460600151611db79190614339565b1115611dd657604051637d6b3cdf60e11b815260040160405180910390fd5b816000036115125760405163090b95c560e31b815260040160405180910390fd5b8151600090819087908790839015611e3a57600087806020019051810190611e1f919061442b565b9050611e2d8b8b8b846120fb565b6020909201519650935091505b855115611e7457600086806020019051810190611e579190614745565b9050611e64838583612572565b6080820151915191965090945090505b9550955095509550959050565b611e8a83612539565b15611e9e57611e998282612822565b505050565b46632b6653dc81148015611ece575073a614f803b6fd780986a42c78ec9c7f77e6ded13c6001600160a01b038516145b15611f7457604080516001600160a01b038581166024830152604480830186905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915191861691611f2a9190614ad3565b6000604051808303816000865af19150503d8060008114611f67576040519150601f19603f3d011682016040523d82523d6000602084013e611f6c565b606091505b5050506119e3565b6119e36001600160a01b038516848461293b565b8047101561139657604051630cfbd6ed60e01b815260040160405180910390fd5b6003546001600160a01b031633146113055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611384565b6001600160e01b03198216600081815260026020908152604091829020805460ff19168515159081179091558251938452908301527fc4a5aadd92b2d0e7efaf25f9d44b0e6fca6c44da8e09fc3250cc12ef954cb60e910160405180910390a15050565b600061207283612539565b1561208857506001600160a01b038116316120f5565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa1580156120ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f29190614aef565b90505b92915050565b805160006001600160a01b038083169087160361212e576040516001624cdd6d60e11b0319815260040160405180910390fd5b600061213e846000015130612067565b905061214b87878661296b565b8061215a856000015130612067565b612164919061434c565b9150836060015182101561218b576040516319af26f360e31b815260040160405180910390fd5b6000856121988930612067565b6121a2919061434c565b905080156121b9576121b988866040015183611e81565b505094509492505050565b600b5460009081906001600160a01b03166121de86612539565b156121f95760208401516121f29086614339565b9150612214565b602084015191506122146001600160a01b0387168287612bf0565b604080850151855160608701519251632e267e4160e21b81526001600160a01b0385169363b899f904938793612256938e938e93928e92909190600401614b08565b60206040518083038185885af1158015612274573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906122999190614aef565b979650505050505050565b600480546001600160a01b031916905561139681612c7f565b604080516060810182526000808252602082018190529181019190915281156120f5576122ec82840184614b5f565b9050600181516001811115612303576123036145c2565b036123625760085481604001511061235d5760405162461bcd60e51b815260206004820152601b60248201527f4665654d616e616765723a20696e76616c6964206665655261746500000000006044820152606401611384565b6120f5565b6009548160400151106120f55760405162461bcd60e51b815260206004820152601e60248201527f4665654d616e616765723a20696e76616c6964206e61746976652066656500006044820152606401611384565b60006001600160a01b0382163b6123e1576040516308ebd80360e11b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0384169081179091556040517f53b7c37d01415b2804281f4684b0722e0b01fbd375bf502609f465e17ab4441e90600090a2506001919050565b612438613a92565b600c546001600160a01b03166124b957604051638239917560e01b81523090638239917590612471908890889088908890600401614a54565b60e060405180830381865afa15801561248e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b29190614bcd565b90506116b5565b600c54604051638239917560e01b81526001600160a01b03909116906382399175906124ef908890889088908890600401614a54565b60e060405180830381865afa15801561250c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125309190614bcd565b95945050505050565b60006001600160a01b03821615806120f557506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b600061257e8330612067565b604083015160a084015191925090602382111561259b5785828201525b83516125a79082612cd1565b60006125b286612539565b156126215784600001516001600160a01b031687836040516125d49190614ad3565b60006040518083038185875af1925050503d8060008114612611576040519150601f19603f3d011682016040523d82523d6000602084013e612616565b606091505b5050809150506126ca565b8615612641576020850151612641906001600160a01b0388169089612dda565b84600001516001600160a01b03168560600151836040516126629190614ad3565b60006040518083038185875af1925050503d806000811461269f576040519150601f19603f3d011682016040523d82523d6000602084013e6126a4565b606091505b509091505086156126ca5760208501516126ca906001600160a01b038816906000612e87565b806126e857604051637588692960e01b815260040160405180910390fd5b6126f28630612067565b612299908561434c565b6001600160a01b0381163b612724576040516308ebd80360e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f556b8b8772c1552cbcc67f9bb7c7fd60934af593e54ec7aa4e8b2683632675f891a250565b6000806000806000806000808880602001905181019061278c9190614c6b565b975097509750975097509750975097506127ac8888888888888888612f9c565b505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526119e39085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613166565b804710156128725760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401611384565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146128bf576040519150601f19603f3d011682016040523d82523d6000602084013e6128c4565b606091505b5050905080611e995760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401611384565b6040516001600160a01b038316602482015260448101829052611e9990849063a9059cbb60e01b906064016127eb565b608081015151600081900361299357604051630239912560e01b815260040160405180910390fd5b60008060006129a78685876080015161323b565b6080880151929550909350915060006129bf89612539565b905060005b86811015612be4578415612abc5780600003612a4d5783612a1557848382815181106129f2576129f2614a25565b6020026020010151606001818151612a0a919061434c565b915081815250612a47565b84838281518110612a2857612a28614a25565b6020026020010151606001818151612a409190614339565b9150818152505b50612abc565b83612a885785838281518110612a6557612a65614a25565b6020026020010151606001818151612a7d919061434c565b915081815250612aba565b85838281518110612a9b57612a9b614a25565b6020026020010151606001818151612ab39190614339565b9150818152505b505b81612b1957612b19838281518110612ad657612ad6614a25565b602002602001015160400151848381518110612af457612af4614a25565b6020026020010151606001518c6001600160a01b0316612dda9092919063ffffffff16565b612b9b838281518110612b2e57612b2e614a25565b60200260200101516000015183858481518110612b4d57612b4d614a25565b6020026020010151602001518d878681518110612b6c57612b6c614a25565b602002602001015160600151888781518110612b8a57612b8a614a25565b602002602001015160800151613325565b81612bdc57612bdc838281518110612bb557612bb5614a25565b60200260200101516040015160008c6001600160a01b0316612e879092919063ffffffff16565b6001016129c4565b50505050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612c4184826133b7565b6119e3576040516001600160a01b038416602482015260006044820152612c7590859063095ea7b360e01b906064016127eb565b6119e38482613166565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000546001600160a01b039081169083168114801590612d0a57506001600160a01b03831660009081526001602052604090205460ff16155b15612d285760405163369370d960e01b815260040160405180910390fd5b6000612d338361345a565b6001600160e01b0319811660009081526002602052604090205490915060ff1615612d7157604051630d1a468960e01b815260040160405180910390fd5b816001600160a01b0316846001600160a01b0316036119e3576001600160e01b03198116632e1a7d4d60e01b14801590612dbc57506001600160e01b03198116630d0e30db60e41b14155b156119e357604051630d1a468960e01b815260040160405180910390fd5b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612e2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4e9190614aef565b90506119e38463095ea7b360e01b85612e678686614339565b6040516001600160a01b03909216602483015260448201526064016127eb565b801580612f015750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612edb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eff9190614aef565b155b612f6c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401611384565b6040516001600160a01b038316602482015260448101829052611e9990849063095ea7b360e01b906064016127eb565b604051623f675f60e91b81526001600160a01b038881166004830152600091908a1690637ecebe0090602401602060405180830381865afa158015612fe5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130099190614aef565b60405163d505accf60e01b81526001600160a01b038a811660048301528981166024830152604482018990526064820188905260ff8716608483015260a4820186905260c48201859052919250908a169063d505accf9060e401600060405180830381600087803b15801561307d57600080fd5b505af1158015613091573d6000803e3d6000fd5b5050604051623f675f60e91b81526001600160a01b038b81166004830152600093508c169150637ecebe0090602401602060405180830381865afa1580156130dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131019190614aef565b905061310e826001614339565b8114612be45760405162461bcd60e51b815260206004820152602160248201527f5361666545524332303a207065726d697420646964206e6f74207375636365656044820152601960fa1b6064820152608401611384565b60006131bb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134759092919063ffffffff16565b90508051600014806131dc5750808060200190518101906131dc9190614cf7565b611e995760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611384565b6000808080805b868110156132875785818151811061325c5761325c614a25565b602002602001015160600151826132739190614339565b91508061327f81614a3b565b915050613242565b50868111156132d357600091508161329f888361434c565b90506132ab8782614a03565b94506132b787866149ec565b6132c1908261434c565b6132cb9086614339565b93505061331b565b8681101561331b576001915060006132eb828961434c565b90506132f78782614a03565b945061330387866149ec565b61330d908261434c565b6133179086614339565b9350505b5093509350939050565b6000600487600581111561333b5761333b6145c2565b036133535761334c85848885613484565b9050613390565b6005876005811115613367576133676145c2565b036133775761334c8484846135d1565b6040516318f9c3a760e11b815260040160405180910390fd5b806133ae57604051636ff55bbf60e01b815260040160405180910390fd5b50505050505050565b6000806000846001600160a01b0316846040516133d49190614ad3565b6000604051808303816000865af19150503d8060008114613411576040519150601f19603f3d011682016040523d82523d6000602084013e613416565b606091505b50915091508180156134405750805115806134405750808060200190518101906134409190614cf7565b80156125305750505050506001600160a01b03163b151590565b6000815160000361346d57506000919050565b506020015190565b60606116b5848460008561387a565b60008060008380602001905181019061349d9190614d14565b8151919350915060005b818110156134ef5760008482815181106134c3576134c3614a25565b6020026020010151905060238111156134dc5788818501525b50806134e781614a3b565b9150506134a7565b506134fa8883612cd1565b851561356657876001600160a01b031687836040516135199190614ad3565b60006040518083038185875af1925050503d8060008114613556576040519150601f19603f3d011682016040523d82523d6000602084013e61355b565b606091505b5050809450506135c6565b876001600160a01b03168260405161357e9190614ad3565b6000604051808303816000865af19150503d80600081146135bb576040519150601f19603f3d011682016040523d82523d6000602084013e6135c0565b606091505b50909450505b505050949350505050565b600080828060200190518101906135e89190614dc5565b905060005b81518110156138715780156136465761362382828151811061361157613611614a25565b60200260200101516020015130612067565b945081818151811061363757613637614a25565b60200260200101516020015195505b600082828151811061365a5761365a614a25565b6020026020010151608001519050600083838151811061367c5761367c614a25565b602002602001015160000151905060238111156136995786818301525b6136c08484815181106136ae576136ae614a25565b60200260200101516040015183612cd1565b6136c988612539565b15613751578383815181106136e0576136e0614a25565b6020026020010151604001516001600160a01b031687836040516137049190614ad3565b60006040518083038185875af1925050503d8060008114613741576040519150601f19603f3d011682016040523d82523d6000602084013e613746565b606091505b505080955050613850565b82156137925761379284848151811061376c5761376c614a25565b602002602001015160600151888a6001600160a01b0316612dda9092919063ffffffff16565b8383815181106137a4576137a4614a25565b6020026020010151604001516001600160a01b0316826040516137c79190614ad3565b6000604051808303816000865af19150503d8060008114613804576040519150601f19603f3d011682016040523d82523d6000602084013e613809565b606091505b509095505082156138505761385084848151811061382957613829614a25565b60200260200101516060015160008a6001600160a01b0316612e879092919063ffffffff16565b8461385c575050613871565b5050808061386990614a3b565b9150506135ed565b50509392505050565b6060824710156138db5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401611384565b600080866001600160a01b031685876040516138f79190614ad3565b60006040518083038185875af1925050503d8060008114613934576040519150601f19603f3d011682016040523d82523d6000602084013e613939565b606091505b509150915061229987838387606083156139b45782516000036139ad576001600160a01b0385163b6139ad5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611384565b50816116b5565b6116b583838151156139c95781518083602001fd5b8060405162461bcd60e51b81526004016113849190614ef0565b604051806101e0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000801916815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b6040518060e0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081525090565b6001600160a01b038116811461139657600080fd5b803561153581613aea565b60008083601f840112613b1c57600080fd5b5081356001600160401b03811115613b3357600080fd5b602083019150836020828501011115613b4b57600080fd5b9250929050565b6000806000806000806000806000806000806101008d8f031215613b7557600080fd5b8c359b50613b8560208e01613aff565b9a50613b9360408e01613aff565b995060608d013598506001600160401b0360808e01351115613bb457600080fd5b613bc48e60808f01358f01613b0a565b90985096506001600160401b0360a08e01351115613be157600080fd5b613bf18e60a08f01358f01613b0a565b90965094506001600160401b0360c08e01351115613c0e57600080fd5b613c1e8e60c08f01358f01613b0a565b90945092506001600160401b0360e08e01351115613c3b57600080fd5b613c4b8e60e08f01358f01613b0a565b81935080925050509295989b509295989b509295989b565b80356001600160e01b03198116811461153557600080fd5b801515811461139657600080fd5b60008060408385031215613c9c57600080fd5b613ca583613c63565b91506020830135613cb581613c7b565b809150509250929050565b600060208284031215613cd257600080fd5b613cdb82613c63565b9392505050565b60008060008060008060008060c0898b031215613cfe57600080fd5b883597506020890135613d1081613aea565b9650604089013595506060890135945060808901356001600160401b0380821115613d3a57600080fd5b613d468c838d01613b0a565b909650945060a08b0135915080821115613d5f57600080fd5b50613d6c8b828c01613b0a565b999c989b5096995094979396929594505050565b60008060408385031215613d9357600080fd5b50508035926020909101359150565b600060208284031215613db457600080fd5b8135613cdb81613aea565b600060208284031215613dd157600080fd5b5035919050565b60008060408385031215613deb57600080fd5b8235613df681613aea565b946020939093013593505050565b60008060008060608587031215613e1a57600080fd5b8435613e2581613aea565b93506020850135925060408501356001600160401b03811115613e4757600080fd5b613e5387828801613b0a565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715613e9757613e97613e5f565b60405290565b60405160c081016001600160401b0381118282101715613e9757613e97613e5f565b604051608081016001600160401b0381118282101715613e9757613e97613e5f565b604051601f8201601f191681016001600160401b0381118282101715613f0957613f09613e5f565b604052919050565b60006001600160401b03821115613f2a57613f2a613e5f565b5060051b60200190565b6006811061139657600080fd5b60006001600160401b03821115613f5a57613f5a613e5f565b50601f01601f191660200190565b600082601f830112613f7957600080fd5b8135613f8c613f8782613f41565b613ee1565b818152846020838601011115613fa157600080fd5b816020850160208301376000918101602001919091529392505050565b600060a08284031215613fd057600080fd5b613fd8613e75565b90508135613fe581613aea565b8152602082810135613ff681613aea565b82820152604083013561400881613aea565b6040830152606083810135818401526080808501356001600160401b038082111561403257600080fd5b818701915087601f83011261404657600080fd5b8135614054613f8782613f11565b81815260059190911b8301860190868101908a83111561407357600080fd5b8785015b8381101561411d5780358581111561408f5760008081fd5b860160a0818e03601f190112156140a65760008081fd5b6140ae613e75565b8a8201356140bb81613f34565b815260408201356140cb81613aea565b818c0152818a01356140dc81613aea565b6040820152818901358a82015260a0820135878111156140fc5760008081fd5b61410a8f8d83860101613f68565b828b015250845250918801918801614077565b5080868a0152505050505050505092915050565b6000806000806080858703121561414757600080fd5b843561415281613aea565b9350602085013592506040850135915060608501356001600160401b0381111561417b57600080fd5b61418787828801613fbe565b91505092959194509250565b6000806000606084860312156141a857600080fd5b83356001600160401b03808211156141bf57600080fd5b9085019060c082880312156141d357600080fd5b6141db613e9d565b82356141e681613aea565b815260208301356141f681613aea565b806020830152506040830135604082015260608301356060820152608083013561421f81613aea565b608082015260a08301358281111561423657600080fd5b61424289828601613f68565b60a083015250945061425991505060208501613aff565b9150604084013590509250925092565b60008060006060848603121561427e57600080fd5b833561428981613aea565b95602085013595506040909401359392505050565b6000806000604084860312156142b357600080fd5b83356001600160401b03808211156142ca57600080fd5b818601915086601f8301126142de57600080fd5b8135818111156142ed57600080fd5b8760208260051b850101111561430257600080fd5b6020928301955093505084013561431881613c7b565b809150509250925092565b634e487b7160e01b600052601160045260246000fd5b808201808211156120f5576120f5614323565b818103818111156120f5576120f5614323565b6000806040838503121561437257600080fd5b82356001600160401b038082111561438957600080fd5b61439586838701613f68565b935060208501359150808211156143ab57600080fd5b506143b885828601613f68565b9150509250929050565b60005b838110156143dd5781810151838201526020016143c5565b50506000910152565b600082601f8301126143f757600080fd5b8151614405613f8782613f41565b81815284602083860101111561441a57600080fd5b6116b58260208301602087016143c2565b6000602080838503121561443e57600080fd5b82516001600160401b038082111561445557600080fd5b9084019060a0828703121561446957600080fd5b614471613e75565b825161447c81613aea565b81528284015161448b81613aea565b81850152604083015161449d81613aea565b604082015260608381015190820152608080840151838111156144bf57600080fd5b80850194505087601f8501126144d457600080fd5b83516144e2613f8782613f11565b81815260059190911b8501860190868101908a83111561450157600080fd5b8787015b838110156145ad5780518781111561451d5760008081fd5b880160a0818e03601f190112156145345760008081fd5b61453c613e75565b8a82015161454981613f34565b8152604082015161455981613aea565b818c0152606082015161456b81613aea565b604082015281870151606082015260a08201518981111561458c5760008081fd5b61459a8f8d838601016143e6565b8289015250845250918801918801614505565b50928401929092525090979650505050505050565b634e487b7160e01b600052602160045260246000fd5b600081518084526145f08160208601602086016143c2565b601f01601f19169290920160200192915050565b6000608060018060a01b038088168452602087818601526040878187015260608481880152610120870184895116868901528389015160a0868216818b015286858c01511660c08b0152838b015160e08b0152878b01519150806101008b01528282518085526101409450848c019150848160051b8d0101945087840193506000805b828110156146ff578d870361013f1901845285518051600681106146b957634e487b7160e01b84526021600452602484fd5b8852808b01518c168b890152898101518c168a89015288810151898901528c01518c88018690526146ec868901826145d8565b9750509489019492890192600101614687565b50505050505080965050505050505095945050505050565b6000806040838503121561472a57600080fd5b825161473581613aea565b6020939093015192949293505050565b60006020828403121561475757600080fd5b81516001600160401b038082111561476e57600080fd5b9083019060c0828603121561478257600080fd5b61478a613e9d565b825161479581613aea565b815260208301516147a581613aea565b80602083015250604083015160408201526060830151606082015260808301516147ce81613aea565b608082015260a0830151828111156147e557600080fd5b6147f1878286016143e6565b60a08301525095945050505050565b60608152600060018060a01b03808651166060840152806020870151166080840152604086015160a0840152606086015160c08401528060808701511660e084015260a086015160c061010085015261485d6101208501826145d8565b959091166020840152505060400152919050565b600061010060018060a01b03808c168452808b166020850152508860408401528760608401528660808401528560a08401528460c08401528060e08401526148bb818401856145d8565b9b9a5050505050505050505050565b6000602082840312156148dc57600080fd5b81356001600160401b038111156148f257600080fd5b6116b584828501613fbe565b60006020828403121561491057600080fd5b81356001600160401b038082111561492757600080fd5b908301906080828603121561493b57600080fd5b614943613ebf565b823581526020830135602082015260408301358281111561496357600080fd5b61496f87828601613f68565b60408301525060608301358281111561498757600080fd5b61499387828601613f68565b60608301525095945050505050565b60006101008a835289602084015260018060a01b03808a1660408501528089166060850152508660808401528560a08401528460c08401528060e08401526148bb818401856145d8565b80820281158282048414176120f5576120f5614323565b600082614a2057634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600060018201614a4d57614a4d614323565b5060010190565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b600080600060608486031215614ab157600080fd5b8351614abc81613aea565b602085015160409095015190969495509392505050565b60008251614ae58184602087016143c2565b9190910192915050565b600060208284031215614b0157600080fd5b5051919050565b6001600160a01b0387811682528616602082015260c060408201819052600090614b34908301876145d8565b85606084015284608084015282810360a0840152614b5281856145d8565b9998505050505050505050565b600060608284031215614b7157600080fd5b604051606081018181106001600160401b0382111715614b9357614b93613e5f565b604052823560028110614ba557600080fd5b81526020830135614bb581613aea565b60208201526040928301359281019290925250919050565b600060e08284031215614bdf57600080fd5b60405160e081018181106001600160401b0382111715614c0157614c01613e5f565b6040528251614c0f81613aea565b81526020830151614c1f81613aea565b60208201526040830151614c3281613aea565b80604083015250606083015160608201526080830151608082015260a083015160a082015260c083015160c08201528091505092915050565b600080600080600080600080610100898b031215614c8857600080fd5b8851614c9381613aea565b60208a0151909850614ca481613aea565b60408a0151909750614cb581613aea565b80965050606089015194506080890151935060a089015160ff81168114614cdb57600080fd5b60c08a015160e0909a0151989b979a5095989497939692505050565b600060208284031215614d0957600080fd5b8151613cdb81613c7b565b60008060408385031215614d2757600080fd5b82516001600160401b0380821115614d3e57600080fd5b818501915085601f830112614d5257600080fd5b81516020614d62613f8783613f11565b82815260059290921b84018101918181019089841115614d8157600080fd5b948201945b83861015614d9f57855182529482019490820190614d86565b91880151919650909350505080821115614db857600080fd5b506143b8858286016143e6565b60006020808385031215614dd857600080fd5b82516001600160401b0380821115614def57600080fd5b818501915085601f830112614e0357600080fd5b8151614e11613f8782613f11565b81815260059190911b83018401908481019088831115614e3057600080fd5b8585015b83811015614ee357805185811115614e4c5760008081fd5b860160a0818c03601f1901811315614e645760008081fd5b614e6c613e75565b898301518152604080840151614e8181613aea565b828c0152606084810151614e9481613aea565b8083850152506080915081850151614eab81613aea565b90830152918301519188831115614ec25760008081fd5b614ed08e8c858701016143e6565b9082015285525050918601918601614e34565b5098975050505050505050565b602081526000613cdb60208301846145d856fea264697066735822122038becc5f4178fb79c9c9f7688f531bb6edfdc8469b83492031e677df022c3acf64736f6c63430008140033000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d93000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Deployed Bytecode
0x6080604052600436106101fd5760003560e01c806385c178301161010d578063c1b1660e116100a0578063d904371e1161006f578063d904371e14610678578063df5d452314610698578063e30c3978146106b8578063f2fde38b146106d6578063f5e53a64146106f657600080fd5b8063c1b1660e146105e8578063d0fb020314610608578063d7fc2da414610628578063d8b964e61461064857600080fd5b8063a3c573eb116100dc578063a3c573eb1461053e578063a73ceca71461055e578063b3f00674146105a8578063bce53d24146105c857600080fd5b806385c17830146104b55780638da5cb5b146104cb5780638dc060ff146104e95780639ccef96f146104ff57600080fd5b806352b2d5431161019057806378e3214f1161015f57806378e3214f1461039d57806379ba5097146103bd5780637ae69a98146103d25780637f5a22f914610417578063823991751461043757600080fd5b806352b2d5431461033f578063536f4cfe146103555780636e1537da14610375578063715018a61461038857600080fd5b80632344e655116101cc5780632344e655146102bb578063278fd202146102db578063472d35b9146102fb5780634e36b11c1461031b57600080fd5b80630babd86414610209578063119b82481461024657806311c4b7721461025b578063227c54121461027b57600080fd5b3661020457005b600080fd5b34801561021557600080fd5b50600054610229906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b610259610254366004613b52565b61070c565b005b34801561026757600080fd5b50610259610276366004613c89565b610a7a565b34801561028757600080fd5b506102ab610296366004613cc0565b60026020526000908152604090205460ff1681565b604051901515815260200161023d565b3480156102c757600080fd5b506102596102d6366004613ce2565b610a90565b3480156102e757600080fd5b506102596102f6366004613d80565b610e7d565b34801561030757600080fd5b50610259610316366004613da2565b610ece565b34801561032757600080fd5b50610331600d5481565b60405190815260200161023d565b34801561034b57600080fd5b5061033160065481565b34801561036157600080fd5b50610259610370366004613dbf565b610f48565b610331610383366004613b52565b610f83565b34801561039457600080fd5b506102596112f3565b3480156103a957600080fd5b506102596103b8366004613dd8565b611307565b3480156103c957600080fd5b5061025961131a565b3480156103de57600080fd5b506103f26103ed366004613e04565b611399565b604080516001600160a01b03909416845260208401929092529082015260600161023d565b34801561042357600080fd5b506102ab610432366004613da2565b61151c565b34801561044357600080fd5b50610457610452366004613e04565b61153a565b6040805182516001600160a01b039081168252602080850151821690830152838301511691810191909152606080830151908201526080808301519082015260a0808301519082015260c0918201519181019190915260e00161023d565b3480156104c157600080fd5b5061033160085481565b3480156104d757600080fd5b506003546001600160a01b0316610229565b3480156104f557600080fd5b5061033160055481565b34801561050b57600080fd5b5061051f61051a366004614131565b6116bd565b604080516001600160a01b03909316835260208301919091520161023d565b34801561054a57600080fd5b50600b54610229906001600160a01b031681565b34801561056a57600080fd5b5061057e610579366004613e04565b6116f9565b604080516001600160a01b039095168552602085019390935291830152606082015260800161023d565b3480156105b457600080fd5b50600754610229906001600160a01b031681565b3480156105d457600080fd5b5061051f6105e3366004614193565b6117af565b3480156105f457600080fd5b50610259610603366004614269565b6117eb565b34801561061457600080fd5b50600c54610229906001600160a01b031681565b34801561063457600080fd5b50610259610643366004613da2565b611882565b34801561065457600080fd5b506102ab610663366004613da2565b60016020526000908152604090205460ff1681565b34801561068457600080fd5b5061025961069336600461429e565b611893565b3480156106a457600080fd5b506103f26106b3366004613e04565b6119e9565b3480156106c457600080fd5b506004546001600160a01b0316610229565b3480156106e257600080fd5b506102596106f1366004613da2565b611afc565b34801561070257600080fd5b5061033160095481565b610714611b6d565b61071c6139e3565b6001600160a01b03808d1660c08301528b1680825260408083018c9052608083018f905280516020601f880181900481028201810190925286815261077f92918d91908990899081908401838280828437600092019190915250611bc692505050565b6101a08301526101808201526107958689614339565b6000036107b5576040516312cd5ab760e11b815260040160405180910390fd5b6107bd613a92565b6107d1826000015183604001518686611c66565b846060018560a001826001600160a01b03166001600160a01b03168152508281525082935050505080604001516001600160a01b031681602001516001600160a01b031683600001516001600160a01b03167ffe2e49614659d9447156c9e3846112ea8edda361dcd696be486f6f977ce854e58460a001518560c0015186606001518760800151896080015160405161088c959493929190948552602085019390935260408401919091526060830152608082015260a00190565b60405180910390a461092882600001518360600151846101a001518d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050508c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611df792505050565b6101208701819052606087018290526001600160a01b039283166020880152928216610100870152921660e085015210156109845761098482602001518360e00151846101200151856060015161097f919061434c565b611e81565b336001600160a01b03168260c001516001600160a01b03168360a001516001600160a01b03167f60656aafa8d4c0a705aeb148b167d7db921d08852cd2261b270d5c7a2e655f83856080015186600001518760200151886040015189606001518a60e001518b61010001518c6101200151604051610a4a9897969594939291909788526001600160a01b039687166020890152948616604088015260608701939093526080860191909152831660a085015290911660c083015260e08201526101000190565b60405180910390a4610a60826101800151611f88565b5050610a6c6001600a55565b505050505050505050505050565b610a82611fa9565b610a8c8282612003565b5050565b610a98611b6d565b610aa06139e3565b6001600160a01b0388168082526040808301899052602080840192909252606083018990526101408301889052466101608401528051601f87018390048302810183019091528581529086908690819084018382808284376000920191909152505050506101c0820152600b546001600160a01b03163314610b35576040516303d6041760e41b815260040160405180910390fd5b6000610b45826000015130612067565b905087811015610b68576040516319af26f360e31b815260040160405180910390fd5b47610180830152610b79888261434c565b6101a083015250600080610b8f8486018661435f565b9150915080518251610ba19190614339565b600003610bc1576040516312cd5ab760e11b815260040160405180910390fd5b600d5482516001919015610ca557600084806020019051810190610be5919061442b565b60208101516001600160a01b031660e08801529050815a1115610ca35730639ccef96f835a610c14919061434c565b88516040808b01516101a08c015191516001600160e01b031960e087901b168152610c459392908890600401614604565b604080518083038160008887f193505050508015610c80575060408051601f3d908101601f19168201909252610c7d91810190614717565b60015b610c8d5760009250610ca3565b6001600160a01b03909116602088015260608701525b505b825115610d9c57600083806020019051810190610cc29190614745565b60e08701519091506001600160a01b0316610ceb5760808101516001600160a01b031660e08701525b828015610cf75750815a115b15610d9a573063bce53d24835a610d0e919061434c565b8389602001518a606001516040518563ffffffff1660e01b8152600401610d3793929190614800565b604080518083038160008887f193505050508015610d72575060408051601f3d908101601f19168201909252610d6f91810190614717565b60015b15610d9a576001600160a01b0391821661010089015261012088015260808201511660e08701525b505b84610120015185606001511115610dcf57610dcf85602001518660e00151876101200151886060015161097f919061434c565b8461010001516001600160a01b03168560e001516001600160a01b03168e7f593e4dbcb8f7312fc3bdd77e2095da131a6e1993f37752d12576d04e1f7253b4886000015189602001518a604001518b606001518c61012001518d61014001518e61016001518f6101c00151604051610e4e989796959493929190614871565b60405180910390a4610e64856101800151611f88565b5050505050610e736001600a55565b5050505050505050565b610e85611fa9565b6127108210610e9357600080fd5b60088290556009819055604051819083907f5b2f81a75439605ecd08ce07af893a489989a97d6d2008dff44c6827503ba82c90600090a35050565b610ed6611fa9565b6001600160a01b0381163b610efe576040516308ebd80360e11b815260040160405180910390fd5b600c80546001600160a01b0319166001600160a01b0383169081179091556040517f5d0517e3a4eabea892d9750138cd21d4a6cf3b935b43d0598df7055f463819b290600090a250565b610f50611fa9565b600d81905560405181907ff47543a7cab136b12cca0a2ecd728c9d1943f57b923b98db48725d2b76dd4da990600090a250565b6000610f8d611b6d565b610f978689614339565b600003610fb7576040516312cd5ab760e11b815260040160405180910390fd5b610fbf6139e3565b8c8160c001906001600160a01b031690816001600160a01b0316815250508b81600001906001600160a01b031690816001600160a01b0316815250508a8160400181815250508b81602001906001600160a01b031690816001600160a01b0316815250508a8160600181815250508d8160800181815250506110808160000151826040015188888080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611bc692505050565b6101a08301526101808201526060611096613a92565b6110aa836000015184604001518888611c66565b6001600160a01b031660a0860152606085015290508a1561116c5760006110d38c8e018e6148ca565b90506110ee84600001518560600151866101a00151846120fb565b60608601526001600160a01b03166020850152891580156111125750606084015115155b1561116a57602080820151604051611142920160609190911b6bffffffffffffffffffffffff1916815260140190565b604051602081830303815290604052925061116a846020015182602001518660600151611e81565b505b88156111ad5760006111808a8c018c6148fe565b80516101608601526040810151602086015160608701519195509192506111a9913391846121c4565b9450505b80604001516001600160a01b031681602001516001600160a01b031684600001516001600160a01b03167ffe2e49614659d9447156c9e3846112ea8edda361dcd696be486f6f977ce854e58460a001518560c00151866060015187608001518b60405161123c959493929190948552602085019390935260408401919091526060830152608082015260a00190565b60405180910390a4336001600160a01b03168360c001516001600160a01b03168460a001516001600160a01b03167fba828651bf4de06e53231285961e555fd7dfe17a3e39d64b09fbaa8ebc0166c6866080015188886000015189602001518a604001518b606001518c61016001518c6040516112c09897969594939291906149a2565b60405180910390a46112d6836101800151611f88565b5050506112e36001600a55565b9c9b505050505050505050505050565b6112fb611fa9565b61130560006122a4565b565b61130f611fa9565b610a8c823383611e81565b60045433906001600160a01b0316811461138d5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b611396816122a4565b50565b6000806000806113a986866122bd565b6007549091506001600160a01b03161580156113d0575060208101516001600160a01b0316155b156113e657600087600093509350935050611512565b6007546000906001600160a01b03161561141a576006546114079084614339565b9250600554816114179190614339565b90505b60208201516001600160a01b03161561146f57600082516001811115611442576114426145c2565b0361145d5760408201516114569084614339565b925061146f565b604082015161146c9082614339565b90505b6001600160a01b03891615806114a1575073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b038a16145b156114ed576114b08389614339565b935080156114e8576114c48161271061434c565b6114d0612710866149ec565b6114da9190614a03565b6114e5906001614339565b93505b61150f565b801561150b576114ff8161271061434c565b6114d06127108a6149ec565b8793505b50505b9450945094915050565b6000611526611fa9565b61152f826123b7565b50600190505b919050565b611542613a92565b600061154e84846122bd565b6007549091506001600160a01b0316158015611575575060208101516001600160a01b0316155b1561158057506116b5565b6001600160a01b038087168352600754161561160c576007546001600160a01b039081166020840152600654606084015286166115eb57612710600554866115c891906149ec565b6115d29190614a03565b826060018181516115e39190614339565b90525061160c565b612710600554866115fc91906149ec565b6116069190614a03565b60a08301525b60208101516001600160a01b0316156116b35760208101516001600160a01b03166040830152600081516001811115611647576116476145c2565b0361165b57604081015160808301526116b3565b6001600160a01b0386166116905761271081604001518661167c91906149ec565b6116869190614a03565b60808301526116b3565b6127108160400151866116a391906149ec565b6116ad9190614a03565b60c08301525b505b949350505050565b6000803330146116e057604051632ee47ea160e11b815260040160405180910390fd5b6116ec868686866120fb565b9097909650945050505050565b600080600080600061170d89898989612430565b80519550905061171c89612539565b1561176a576000935080608001518160c001518260a0015183606001516117439190614339565b61174d9190614339565b6117579190614339565b9250611763838961434c565b91506117a3565b8060c001518160a0015161177e9190614339565b9350806080015181606001516117949190614339565b92506117a0848961434c565b91505b50945094509450949050565b6000803330146117d257604051632ee47ea160e11b815260040160405180910390fd5b845191506117e1838587612572565b9050935093915050565b6117f3611fa9565b6001600160a01b03831661181a5760405163538ba4f960e01b815260040160405180910390fd5b612710821061182857600080fd5b600780546001600160a01b0319166001600160a01b03851690811790915560058390556006829055604051829184917f17906aa05b055ced1cea92b104912638c3ec8c90eec152fca6f36fbd8becca1d90600090a4505050565b61188a611fa9565b611396816126fc565b61189b611fa9565b60008290036118bd57604051630239912560e01b815260040160405180910390fd5b60005b828110156119e3576119018484838181106118dd576118dd614a25565b90506020020160208101906118f29190613da2565b6001600160a01b03163b151590565b61191e576040516308ebd80360e11b815260040160405180910390fd5b816001600086868581811061193557611935614a25565b905060200201602081019061194a9190613da2565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905581151584848381811061198757611987614a25565b905060200201602081019061199c9190613da2565b6001600160a01b03167f1f478f1e5aee36a892d86e821aba410dc0934cb0ebd0241dd75370833884545360405160405180910390a3806119db81614a3b565b9150506118c0565b50505050565b600c54600090819081906001600160a01b0316611a7557604051630f5cd35360e31b81523090637ae69a9890611a29908a908a908a908a90600401614a54565b606060405180830381865afa158015611a46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a6a9190614a9c565b925092509250611512565b600c54604051630f5cd35360e31b81526001600160a01b0390911690637ae69a9890611aab908a908a908a908a90600401614a54565b606060405180830381865afa158015611ac8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aec9190614a9c565b9250925092509450945094915050565b611b04611fa9565b600480546001600160a01b0383166001600160a01b03199091168117909155611b356003546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b6002600a5403611bbf5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611384565b6002600a55565b60008083600003611bea5760405163090b95c560e31b815260040160405180910390fd5b825115611bfa57611bfa8361276c565b611c04344761434c565b9150611c0f85612539565b15611c465783341015611c3557604051637d6b3cdf60e11b815260040160405180910390fd5b611c3f844761434c565b9050611c5e565b611c508530612067565b9050611c5e853330876127b7565b935093915050565b611c6e613a92565b600080611c7d87878787612430565b925082604001519050611c8f87612539565b15611d0c5760008360a001518460600151611caa9190614339565b90508015611cc157611cc188856020015183611e81565b600084608001518560c00151611cd79190614339565b90508015611cee57611cee89866040015183611e81565b80611cf9838a61434c565b611d03919061434c565b93505050611dd6565b606083015115611d2a57611d2a600084602001518560600151611e81565b60a083015115611d4757611d478784602001518560a00151611e81565b608083015115611d6557611d65600084604001518560800151611e81565b60c083015115611d8257611d828784604001518560c00151611e81565b60c083015160a0840151611d96908861434c565b611da0919061434c565b91503483608001518460600151611db79190614339565b1115611dd657604051637d6b3cdf60e11b815260040160405180910390fd5b816000036115125760405163090b95c560e31b815260040160405180910390fd5b8151600090819087908790839015611e3a57600087806020019051810190611e1f919061442b565b9050611e2d8b8b8b846120fb565b6020909201519650935091505b855115611e7457600086806020019051810190611e579190614745565b9050611e64838583612572565b6080820151915191965090945090505b9550955095509550959050565b611e8a83612539565b15611e9e57611e998282612822565b505050565b46632b6653dc81148015611ece575073a614f803b6fd780986a42c78ec9c7f77e6ded13c6001600160a01b038516145b15611f7457604080516001600160a01b038581166024830152604480830186905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915191861691611f2a9190614ad3565b6000604051808303816000865af19150503d8060008114611f67576040519150601f19603f3d011682016040523d82523d6000602084013e611f6c565b606091505b5050506119e3565b6119e36001600160a01b038516848461293b565b8047101561139657604051630cfbd6ed60e01b815260040160405180910390fd5b6003546001600160a01b031633146113055760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401611384565b6001600160e01b03198216600081815260026020908152604091829020805460ff19168515159081179091558251938452908301527fc4a5aadd92b2d0e7efaf25f9d44b0e6fca6c44da8e09fc3250cc12ef954cb60e910160405180910390a15050565b600061207283612539565b1561208857506001600160a01b038116316120f5565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa1580156120ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f29190614aef565b90505b92915050565b805160006001600160a01b038083169087160361212e576040516001624cdd6d60e11b0319815260040160405180910390fd5b600061213e846000015130612067565b905061214b87878661296b565b8061215a856000015130612067565b612164919061434c565b9150836060015182101561218b576040516319af26f360e31b815260040160405180910390fd5b6000856121988930612067565b6121a2919061434c565b905080156121b9576121b988866040015183611e81565b505094509492505050565b600b5460009081906001600160a01b03166121de86612539565b156121f95760208401516121f29086614339565b9150612214565b602084015191506122146001600160a01b0387168287612bf0565b604080850151855160608701519251632e267e4160e21b81526001600160a01b0385169363b899f904938793612256938e938e93928e92909190600401614b08565b60206040518083038185885af1158015612274573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906122999190614aef565b979650505050505050565b600480546001600160a01b031916905561139681612c7f565b604080516060810182526000808252602082018190529181019190915281156120f5576122ec82840184614b5f565b9050600181516001811115612303576123036145c2565b036123625760085481604001511061235d5760405162461bcd60e51b815260206004820152601b60248201527f4665654d616e616765723a20696e76616c6964206665655261746500000000006044820152606401611384565b6120f5565b6009548160400151106120f55760405162461bcd60e51b815260206004820152601e60248201527f4665654d616e616765723a20696e76616c6964206e61746976652066656500006044820152606401611384565b60006001600160a01b0382163b6123e1576040516308ebd80360e11b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0384169081179091556040517f53b7c37d01415b2804281f4684b0722e0b01fbd375bf502609f465e17ab4441e90600090a2506001919050565b612438613a92565b600c546001600160a01b03166124b957604051638239917560e01b81523090638239917590612471908890889088908890600401614a54565b60e060405180830381865afa15801561248e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b29190614bcd565b90506116b5565b600c54604051638239917560e01b81526001600160a01b03909116906382399175906124ef908890889088908890600401614a54565b60e060405180830381865afa15801561250c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125309190614bcd565b95945050505050565b60006001600160a01b03821615806120f557506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b600061257e8330612067565b604083015160a084015191925090602382111561259b5785828201525b83516125a79082612cd1565b60006125b286612539565b156126215784600001516001600160a01b031687836040516125d49190614ad3565b60006040518083038185875af1925050503d8060008114612611576040519150601f19603f3d011682016040523d82523d6000602084013e612616565b606091505b5050809150506126ca565b8615612641576020850151612641906001600160a01b0388169089612dda565b84600001516001600160a01b03168560600151836040516126629190614ad3565b60006040518083038185875af1925050503d806000811461269f576040519150601f19603f3d011682016040523d82523d6000602084013e6126a4565b606091505b509091505086156126ca5760208501516126ca906001600160a01b038816906000612e87565b806126e857604051637588692960e01b815260040160405180910390fd5b6126f28630612067565b612299908561434c565b6001600160a01b0381163b612724576040516308ebd80360e11b815260040160405180910390fd5b600080546001600160a01b0319166001600160a01b038316908117825560405190917f556b8b8772c1552cbcc67f9bb7c7fd60934af593e54ec7aa4e8b2683632675f891a250565b6000806000806000806000808880602001905181019061278c9190614c6b565b975097509750975097509750975097506127ac8888888888888888612f9c565b505050505050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526119e39085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613166565b804710156128725760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401611384565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146128bf576040519150601f19603f3d011682016040523d82523d6000602084013e6128c4565b606091505b5050905080611e995760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401611384565b6040516001600160a01b038316602482015260448101829052611e9990849063a9059cbb60e01b906064016127eb565b608081015151600081900361299357604051630239912560e01b815260040160405180910390fd5b60008060006129a78685876080015161323b565b6080880151929550909350915060006129bf89612539565b905060005b86811015612be4578415612abc5780600003612a4d5783612a1557848382815181106129f2576129f2614a25565b6020026020010151606001818151612a0a919061434c565b915081815250612a47565b84838281518110612a2857612a28614a25565b6020026020010151606001818151612a409190614339565b9150818152505b50612abc565b83612a885785838281518110612a6557612a65614a25565b6020026020010151606001818151612a7d919061434c565b915081815250612aba565b85838281518110612a9b57612a9b614a25565b6020026020010151606001818151612ab39190614339565b9150818152505b505b81612b1957612b19838281518110612ad657612ad6614a25565b602002602001015160400151848381518110612af457612af4614a25565b6020026020010151606001518c6001600160a01b0316612dda9092919063ffffffff16565b612b9b838281518110612b2e57612b2e614a25565b60200260200101516000015183858481518110612b4d57612b4d614a25565b6020026020010151602001518d878681518110612b6c57612b6c614a25565b602002602001015160600151888781518110612b8a57612b8a614a25565b602002602001015160800151613325565b81612bdc57612bdc838281518110612bb557612bb5614a25565b60200260200101516040015160008c6001600160a01b0316612e879092919063ffffffff16565b6001016129c4565b50505050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b179052612c4184826133b7565b6119e3576040516001600160a01b038416602482015260006044820152612c7590859063095ea7b360e01b906064016127eb565b6119e38482613166565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000546001600160a01b039081169083168114801590612d0a57506001600160a01b03831660009081526001602052604090205460ff16155b15612d285760405163369370d960e01b815260040160405180910390fd5b6000612d338361345a565b6001600160e01b0319811660009081526002602052604090205490915060ff1615612d7157604051630d1a468960e01b815260040160405180910390fd5b816001600160a01b0316846001600160a01b0316036119e3576001600160e01b03198116632e1a7d4d60e01b14801590612dbc57506001600160e01b03198116630d0e30db60e41b14155b156119e357604051630d1a468960e01b815260040160405180910390fd5b604051636eb1769f60e11b81523060048201526001600160a01b0383811660248301526000919085169063dd62ed3e90604401602060405180830381865afa158015612e2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4e9190614aef565b90506119e38463095ea7b360e01b85612e678686614339565b6040516001600160a01b03909216602483015260448201526064016127eb565b801580612f015750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612edb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eff9190614aef565b155b612f6c5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401611384565b6040516001600160a01b038316602482015260448101829052611e9990849063095ea7b360e01b906064016127eb565b604051623f675f60e91b81526001600160a01b038881166004830152600091908a1690637ecebe0090602401602060405180830381865afa158015612fe5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130099190614aef565b60405163d505accf60e01b81526001600160a01b038a811660048301528981166024830152604482018990526064820188905260ff8716608483015260a4820186905260c48201859052919250908a169063d505accf9060e401600060405180830381600087803b15801561307d57600080fd5b505af1158015613091573d6000803e3d6000fd5b5050604051623f675f60e91b81526001600160a01b038b81166004830152600093508c169150637ecebe0090602401602060405180830381865afa1580156130dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131019190614aef565b905061310e826001614339565b8114612be45760405162461bcd60e51b815260206004820152602160248201527f5361666545524332303a207065726d697420646964206e6f74207375636365656044820152601960fa1b6064820152608401611384565b60006131bb826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166134759092919063ffffffff16565b90508051600014806131dc5750808060200190518101906131dc9190614cf7565b611e995760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611384565b6000808080805b868110156132875785818151811061325c5761325c614a25565b602002602001015160600151826132739190614339565b91508061327f81614a3b565b915050613242565b50868111156132d357600091508161329f888361434c565b90506132ab8782614a03565b94506132b787866149ec565b6132c1908261434c565b6132cb9086614339565b93505061331b565b8681101561331b576001915060006132eb828961434c565b90506132f78782614a03565b945061330387866149ec565b61330d908261434c565b6133179086614339565b9350505b5093509350939050565b6000600487600581111561333b5761333b6145c2565b036133535761334c85848885613484565b9050613390565b6005876005811115613367576133676145c2565b036133775761334c8484846135d1565b6040516318f9c3a760e11b815260040160405180910390fd5b806133ae57604051636ff55bbf60e01b815260040160405180910390fd5b50505050505050565b6000806000846001600160a01b0316846040516133d49190614ad3565b6000604051808303816000865af19150503d8060008114613411576040519150601f19603f3d011682016040523d82523d6000602084013e613416565b606091505b50915091508180156134405750805115806134405750808060200190518101906134409190614cf7565b80156125305750505050506001600160a01b03163b151590565b6000815160000361346d57506000919050565b506020015190565b60606116b5848460008561387a565b60008060008380602001905181019061349d9190614d14565b8151919350915060005b818110156134ef5760008482815181106134c3576134c3614a25565b6020026020010151905060238111156134dc5788818501525b50806134e781614a3b565b9150506134a7565b506134fa8883612cd1565b851561356657876001600160a01b031687836040516135199190614ad3565b60006040518083038185875af1925050503d8060008114613556576040519150601f19603f3d011682016040523d82523d6000602084013e61355b565b606091505b5050809450506135c6565b876001600160a01b03168260405161357e9190614ad3565b6000604051808303816000865af19150503d80600081146135bb576040519150601f19603f3d011682016040523d82523d6000602084013e6135c0565b606091505b50909450505b505050949350505050565b600080828060200190518101906135e89190614dc5565b905060005b81518110156138715780156136465761362382828151811061361157613611614a25565b60200260200101516020015130612067565b945081818151811061363757613637614a25565b60200260200101516020015195505b600082828151811061365a5761365a614a25565b6020026020010151608001519050600083838151811061367c5761367c614a25565b602002602001015160000151905060238111156136995786818301525b6136c08484815181106136ae576136ae614a25565b60200260200101516040015183612cd1565b6136c988612539565b15613751578383815181106136e0576136e0614a25565b6020026020010151604001516001600160a01b031687836040516137049190614ad3565b60006040518083038185875af1925050503d8060008114613741576040519150601f19603f3d011682016040523d82523d6000602084013e613746565b606091505b505080955050613850565b82156137925761379284848151811061376c5761376c614a25565b602002602001015160600151888a6001600160a01b0316612dda9092919063ffffffff16565b8383815181106137a4576137a4614a25565b6020026020010151604001516001600160a01b0316826040516137c79190614ad3565b6000604051808303816000865af19150503d8060008114613804576040519150601f19603f3d011682016040523d82523d6000602084013e613809565b606091505b509095505082156138505761385084848151811061382957613829614a25565b60200260200101516060015160008a6001600160a01b0316612e879092919063ffffffff16565b8461385c575050613871565b5050808061386990614a3b565b9150506135ed565b50509392505050565b6060824710156138db5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401611384565b600080866001600160a01b031685876040516138f79190614ad3565b60006040518083038185875af1925050503d8060008114613934576040519150601f19603f3d011682016040523d82523d6000602084013e613939565b606091505b509150915061229987838387606083156139b45782516000036139ad576001600160a01b0385163b6139ad5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611384565b50816116b5565b6116b583838151156139c95781518083602001fd5b8060405162461bcd60e51b81526004016113849190614ef0565b604051806101e0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160008152602001600081526020016000801916815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b6040518060e0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b03168152602001600081526020016000815260200160008152602001600081525090565b6001600160a01b038116811461139657600080fd5b803561153581613aea565b60008083601f840112613b1c57600080fd5b5081356001600160401b03811115613b3357600080fd5b602083019150836020828501011115613b4b57600080fd5b9250929050565b6000806000806000806000806000806000806101008d8f031215613b7557600080fd5b8c359b50613b8560208e01613aff565b9a50613b9360408e01613aff565b995060608d013598506001600160401b0360808e01351115613bb457600080fd5b613bc48e60808f01358f01613b0a565b90985096506001600160401b0360a08e01351115613be157600080fd5b613bf18e60a08f01358f01613b0a565b90965094506001600160401b0360c08e01351115613c0e57600080fd5b613c1e8e60c08f01358f01613b0a565b90945092506001600160401b0360e08e01351115613c3b57600080fd5b613c4b8e60e08f01358f01613b0a565b81935080925050509295989b509295989b509295989b565b80356001600160e01b03198116811461153557600080fd5b801515811461139657600080fd5b60008060408385031215613c9c57600080fd5b613ca583613c63565b91506020830135613cb581613c7b565b809150509250929050565b600060208284031215613cd257600080fd5b613cdb82613c63565b9392505050565b60008060008060008060008060c0898b031215613cfe57600080fd5b883597506020890135613d1081613aea565b9650604089013595506060890135945060808901356001600160401b0380821115613d3a57600080fd5b613d468c838d01613b0a565b909650945060a08b0135915080821115613d5f57600080fd5b50613d6c8b828c01613b0a565b999c989b5096995094979396929594505050565b60008060408385031215613d9357600080fd5b50508035926020909101359150565b600060208284031215613db457600080fd5b8135613cdb81613aea565b600060208284031215613dd157600080fd5b5035919050565b60008060408385031215613deb57600080fd5b8235613df681613aea565b946020939093013593505050565b60008060008060608587031215613e1a57600080fd5b8435613e2581613aea565b93506020850135925060408501356001600160401b03811115613e4757600080fd5b613e5387828801613b0a565b95989497509550505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b0381118282101715613e9757613e97613e5f565b60405290565b60405160c081016001600160401b0381118282101715613e9757613e97613e5f565b604051608081016001600160401b0381118282101715613e9757613e97613e5f565b604051601f8201601f191681016001600160401b0381118282101715613f0957613f09613e5f565b604052919050565b60006001600160401b03821115613f2a57613f2a613e5f565b5060051b60200190565b6006811061139657600080fd5b60006001600160401b03821115613f5a57613f5a613e5f565b50601f01601f191660200190565b600082601f830112613f7957600080fd5b8135613f8c613f8782613f41565b613ee1565b818152846020838601011115613fa157600080fd5b816020850160208301376000918101602001919091529392505050565b600060a08284031215613fd057600080fd5b613fd8613e75565b90508135613fe581613aea565b8152602082810135613ff681613aea565b82820152604083013561400881613aea565b6040830152606083810135818401526080808501356001600160401b038082111561403257600080fd5b818701915087601f83011261404657600080fd5b8135614054613f8782613f11565b81815260059190911b8301860190868101908a83111561407357600080fd5b8785015b8381101561411d5780358581111561408f5760008081fd5b860160a0818e03601f190112156140a65760008081fd5b6140ae613e75565b8a8201356140bb81613f34565b815260408201356140cb81613aea565b818c0152818a01356140dc81613aea565b6040820152818901358a82015260a0820135878111156140fc5760008081fd5b61410a8f8d83860101613f68565b828b015250845250918801918801614077565b5080868a0152505050505050505092915050565b6000806000806080858703121561414757600080fd5b843561415281613aea565b9350602085013592506040850135915060608501356001600160401b0381111561417b57600080fd5b61418787828801613fbe565b91505092959194509250565b6000806000606084860312156141a857600080fd5b83356001600160401b03808211156141bf57600080fd5b9085019060c082880312156141d357600080fd5b6141db613e9d565b82356141e681613aea565b815260208301356141f681613aea565b806020830152506040830135604082015260608301356060820152608083013561421f81613aea565b608082015260a08301358281111561423657600080fd5b61424289828601613f68565b60a083015250945061425991505060208501613aff565b9150604084013590509250925092565b60008060006060848603121561427e57600080fd5b833561428981613aea565b95602085013595506040909401359392505050565b6000806000604084860312156142b357600080fd5b83356001600160401b03808211156142ca57600080fd5b818601915086601f8301126142de57600080fd5b8135818111156142ed57600080fd5b8760208260051b850101111561430257600080fd5b6020928301955093505084013561431881613c7b565b809150509250925092565b634e487b7160e01b600052601160045260246000fd5b808201808211156120f5576120f5614323565b818103818111156120f5576120f5614323565b6000806040838503121561437257600080fd5b82356001600160401b038082111561438957600080fd5b61439586838701613f68565b935060208501359150808211156143ab57600080fd5b506143b885828601613f68565b9150509250929050565b60005b838110156143dd5781810151838201526020016143c5565b50506000910152565b600082601f8301126143f757600080fd5b8151614405613f8782613f41565b81815284602083860101111561441a57600080fd5b6116b58260208301602087016143c2565b6000602080838503121561443e57600080fd5b82516001600160401b038082111561445557600080fd5b9084019060a0828703121561446957600080fd5b614471613e75565b825161447c81613aea565b81528284015161448b81613aea565b81850152604083015161449d81613aea565b604082015260608381015190820152608080840151838111156144bf57600080fd5b80850194505087601f8501126144d457600080fd5b83516144e2613f8782613f11565b81815260059190911b8501860190868101908a83111561450157600080fd5b8787015b838110156145ad5780518781111561451d5760008081fd5b880160a0818e03601f190112156145345760008081fd5b61453c613e75565b8a82015161454981613f34565b8152604082015161455981613aea565b818c0152606082015161456b81613aea565b604082015281870151606082015260a08201518981111561458c5760008081fd5b61459a8f8d838601016143e6565b8289015250845250918801918801614505565b50928401929092525090979650505050505050565b634e487b7160e01b600052602160045260246000fd5b600081518084526145f08160208601602086016143c2565b601f01601f19169290920160200192915050565b6000608060018060a01b038088168452602087818601526040878187015260608481880152610120870184895116868901528389015160a0868216818b015286858c01511660c08b0152838b015160e08b0152878b01519150806101008b01528282518085526101409450848c019150848160051b8d0101945087840193506000805b828110156146ff578d870361013f1901845285518051600681106146b957634e487b7160e01b84526021600452602484fd5b8852808b01518c168b890152898101518c168a89015288810151898901528c01518c88018690526146ec868901826145d8565b9750509489019492890192600101614687565b50505050505080965050505050505095945050505050565b6000806040838503121561472a57600080fd5b825161473581613aea565b6020939093015192949293505050565b60006020828403121561475757600080fd5b81516001600160401b038082111561476e57600080fd5b9083019060c0828603121561478257600080fd5b61478a613e9d565b825161479581613aea565b815260208301516147a581613aea565b80602083015250604083015160408201526060830151606082015260808301516147ce81613aea565b608082015260a0830151828111156147e557600080fd5b6147f1878286016143e6565b60a08301525095945050505050565b60608152600060018060a01b03808651166060840152806020870151166080840152604086015160a0840152606086015160c08401528060808701511660e084015260a086015160c061010085015261485d6101208501826145d8565b959091166020840152505060400152919050565b600061010060018060a01b03808c168452808b166020850152508860408401528760608401528660808401528560a08401528460c08401528060e08401526148bb818401856145d8565b9b9a5050505050505050505050565b6000602082840312156148dc57600080fd5b81356001600160401b038111156148f257600080fd5b6116b584828501613fbe565b60006020828403121561491057600080fd5b81356001600160401b038082111561492757600080fd5b908301906080828603121561493b57600080fd5b614943613ebf565b823581526020830135602082015260408301358281111561496357600080fd5b61496f87828601613f68565b60408301525060608301358281111561498757600080fd5b61499387828601613f68565b60608301525095945050505050565b60006101008a835289602084015260018060a01b03808a1660408501528089166060850152508660808401528560a08401528460c08401528060e08401526148bb818401856145d8565b80820281158282048414176120f5576120f5614323565b600082614a2057634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b600060018201614a4d57614a4d614323565b5060010190565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b600080600060608486031215614ab157600080fd5b8351614abc81613aea565b602085015160409095015190969495509392505050565b60008251614ae58184602087016143c2565b9190910192915050565b600060208284031215614b0157600080fd5b5051919050565b6001600160a01b0387811682528616602082015260c060408201819052600090614b34908301876145d8565b85606084015284608084015282810360a0840152614b5281856145d8565b9998505050505050505050565b600060608284031215614b7157600080fd5b604051606081018181106001600160401b0382111715614b9357614b93613e5f565b604052823560028110614ba557600080fd5b81526020830135614bb581613aea565b60208201526040928301359281019290925250919050565b600060e08284031215614bdf57600080fd5b60405160e081018181106001600160401b0382111715614c0157614c01613e5f565b6040528251614c0f81613aea565b81526020830151614c1f81613aea565b60208201526040830151614c3281613aea565b80604083015250606083015160608201526080830151608082015260a083015160a082015260c083015160c08201528091505092915050565b600080600080600080600080610100898b031215614c8857600080fd5b8851614c9381613aea565b60208a0151909850614ca481613aea565b60408a0151909750614cb581613aea565b80965050606089015194506080890151935060a089015160ff81168114614cdb57600080fd5b60c08a015160e0909a0151989b979a5095989497939692505050565b600060208284031215614d0957600080fd5b8151613cdb81613c7b565b60008060408385031215614d2757600080fd5b82516001600160401b0380821115614d3e57600080fd5b818501915085601f830112614d5257600080fd5b81516020614d62613f8783613f11565b82815260059290921b84018101918181019089841115614d8157600080fd5b948201945b83861015614d9f57855182529482019490820190614d86565b91880151919650909350505080821115614db857600080fd5b506143b8858286016143e6565b60006020808385031215614dd857600080fd5b82516001600160401b0380821115614def57600080fd5b818501915085601f830112614e0357600080fd5b8151614e11613f8782613f11565b81815260059190911b83018401908481019088831115614e3057600080fd5b8585015b83811015614ee357805185811115614e4c5760008081fd5b860160a0818c03601f1901811315614e645760008081fd5b614e6c613e75565b898301518152604080840151614e8181613aea565b828c0152606084810151614e9481613aea565b8083850152506080915081850151614eab81613aea565b90830152918301519188831115614ec25760008081fd5b614ed08e8c858701016143e6565b9082015285525050918601918601614e34565b5098975050505050505050565b602081526000613cdb60208301846145d856fea264697066735822122038becc5f4178fb79c9c9f7688f531bb6edfdc8469b83492031e677df022c3acf64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d93000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
-----Decoded View---------------
Arg [0] : _bridgeAddress (address): 0xfeB2b97e4Efce787c08086dC16Ab69E063911380
Arg [1] : _owner (address): 0xdf3f1Ee5BAF55055980887AaD79F6fE6e3302D93
Arg [2] : _wToken (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000feb2b97e4efce787c08086dc16ab69e063911380
Arg [1] : 000000000000000000000000df3f1ee5baf55055980887aad79f6fe6e3302d93
Arg [2] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 38.88% | $3,209.78 | 0.000000000000000378 | <$0.000001 |
BSC | 21.63% | $684.52 | 0.000000000000000986 | <$0.000001 | |
BASE | 17.89% | $3,208.74 | 0.000000000000000174 | <$0.000001 | |
ARB | 15.43% | $3,209.74 | 0.00000000000000015 | <$0.000001 | |
OP | 2.88% | $3,209.78 | 0.000000000000000028 | <$0.000001 | |
BLAST | 2.37% | $3,209.75 | 0.000000000000000023 | <$0.000001 | |
SCROLL | 0.51% | $3,209.53 | 0.000000000000000005 | <$0.000001 | |
LINEA | 0.41% | $3,209.53 | 0.000000000000000004 | <$0.000001 | |
POL | <0.01% | $0.432602 | 0.000000000000000096 | <$0.000001 | |
MANTLE | <0.01% | $1.17 | 0.000000000000000003 | <$0.000001 |
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.