Overview
S Balance
0 S
S Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 8 from a total of 8 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Adapters | 3287470 | 2 days ago | IN | 0 S | 0.00032687 | ||||
Set Adapters | 3283104 | 2 days ago | IN | 0 S | 0.00043708 | ||||
Set Adapters | 3281737 | 2 days ago | IN | 0 S | 0.00041955 | ||||
Set Adapters | 3167827 | 3 days ago | IN | 0 S | 0.00083981 | ||||
Set Adapters | 3166863 | 3 days ago | IN | 0 S | 0.00027499 | ||||
Set Adapters | 3165206 | 3 days ago | IN | 0 S | 0.00040201 | ||||
Set Adapters | 3158943 | 3 days ago | IN | 0 S | 0.00038447 | ||||
Set Adapters | 3036251 | 4 days ago | IN | 0 S | 0.00036694 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
3629148 | 10 hrs ago | 85.01456206 S | ||||
3629148 | 10 hrs ago | 85.01456206 S | ||||
3626788 | 10 hrs ago | 85.02874347 S | ||||
3626788 | 10 hrs ago | 85.02874347 S | ||||
3626309 | 10 hrs ago | 85.17234847 S | ||||
3626309 | 10 hrs ago | 85.17234847 S | ||||
3573610 | 16 hrs ago | 85.00123964 S | ||||
3573610 | 16 hrs ago | 85.00123964 S | ||||
3573583 | 16 hrs ago | 85.00481972 S | ||||
3573583 | 16 hrs ago | 85.00481972 S | ||||
3573552 | 16 hrs ago | 85.00437838 S | ||||
3573552 | 16 hrs ago | 85.00437838 S | ||||
3573267 | 17 hrs ago | 85.00109228 S | ||||
3573267 | 17 hrs ago | 85.00109228 S | ||||
3573134 | 17 hrs ago | 85.00044836 S | ||||
3573134 | 17 hrs ago | 85.00044836 S | ||||
3565851 | 17 hrs ago | 85.00008649 S | ||||
3565851 | 17 hrs ago | 85.00008649 S | ||||
3551695 | 19 hrs ago | 85.0084389 S | ||||
3551695 | 19 hrs ago | 85.0084389 S | ||||
3548904 | 20 hrs ago | 85.14956009 S | ||||
3548904 | 20 hrs ago | 85.14956009 S | ||||
3523606 | 23 hrs ago | 85.005626 S | ||||
3523606 | 23 hrs ago | 85.005626 S | ||||
3523312 | 23 hrs ago | 85.05556868 S |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
YakRouter
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 1000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// ╟╗ ╔╬ // ╞╬╬ ╬╠╬ // ╔╣╬╬╬ ╠╠╠╠╦ // ╬╬╬╬╬╩ ╘╠╠╠╠╬ // ║╬╬╬╬╬ ╘╠╠╠╠╬ // ╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╒╬╬╬╬╬╬╬╜ ╠╠╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╬╬╬╬╬╬╬╬╠╠╠╠╠╠╠╠ // ╙╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╕ ╬╬╬╬╬╬╬╜ ╣╠╠╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╬╬╬╬╬╬╬╬╬╠╠╠╠╠╠╠╩ // ╙╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╔╬╬╬╬╬╬╬ ╔╠╠╠╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╣╬╬╬╬╬╬╬╬╬╬╬╠╠╠╠╝╙ // ╘╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╒╠╠╠╬╠╬╩╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╣╬╬╬╬╬╬╬╙ // ╣╬╬╬╬╬╬╬╬╬╬╠╣ ╣╬╠╠╠╬╩ ╚╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╬╬╬╬╬╬╬ // ╣╬╬╬╬╬╬╬╬╬╣ ╣╬╠╠╠╬╬ ╣╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╬╬╬╬╬╬╬ // ╟╬╬╬╬╬╬╬╩ ╬╬╠╠╠╠╬╬╬╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╠╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╒╬╬╠╠╬╠╠╬╬╬╬╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╣╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╬╬╬╠╠╠╠╝╝╝╝╝╝╝╠╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╚╬╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╣╬╬╬╬╠╠╩ ╘╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╙╬╬╬╬╬╬╬╬ // // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.0; pragma experimental ABIEncoderV2; import "./interface/IYakRouter.sol"; import "./interface/IAdapter.sol"; import "./interface/IERC20.sol"; import "./interface/IWETH.sol"; import "./lib/SafeERC20.sol"; import "./lib/Maintainable.sol"; import "./lib/YakViewUtils.sol"; import "./lib/Recoverable.sol"; import "./lib/SafeERC20.sol"; contract YakRouter is Maintainable, Recoverable, IYakRouter { using SafeERC20 for IERC20; using OfferUtils for Offer; address public immutable WNATIVE; address public constant NATIVE = address(0); string public constant NAME = "YakRouter"; uint256 public constant FEE_DENOMINATOR = 1e4; uint256 public MIN_FEE = 0; address public FEE_CLAIMER; address[] public TRUSTED_TOKENS; address[] public ADAPTERS; constructor( address[] memory _adapters, address[] memory _trustedTokens, address _feeClaimer, address _wrapped_native ) { setAllowanceForWrapping(_wrapped_native); setTrustedTokens(_trustedTokens); setFeeClaimer(_feeClaimer); setAdapters(_adapters); WNATIVE = _wrapped_native; } // -- SETTERS -- function setAllowanceForWrapping(address _wnative) public onlyMaintainer { IERC20(_wnative).safeApprove(_wnative, type(uint256).max); } function setTrustedTokens(address[] memory _trustedTokens) override public onlyMaintainer { emit UpdatedTrustedTokens(_trustedTokens); TRUSTED_TOKENS = _trustedTokens; } function setAdapters(address[] memory _adapters) override public onlyMaintainer { emit UpdatedAdapters(_adapters); ADAPTERS = _adapters; } function setMinFee(uint256 _fee) override external onlyMaintainer { emit UpdatedMinFee(MIN_FEE, _fee); MIN_FEE = _fee; } function setFeeClaimer(address _claimer) override public onlyMaintainer { emit UpdatedFeeClaimer(FEE_CLAIMER, _claimer); FEE_CLAIMER = _claimer; } // -- GENERAL -- function trustedTokensCount() override external view returns (uint256) { return TRUSTED_TOKENS.length; } function adaptersCount() override external view returns (uint256) { return ADAPTERS.length; } // Fallback receive() external payable {} // -- HELPERS -- function _applyFee(uint256 _amountIn, uint256 _fee) internal view returns (uint256) { require(_fee >= MIN_FEE, "YakRouter: Insufficient fee"); return (_amountIn * (FEE_DENOMINATOR - _fee)) / FEE_DENOMINATOR; } function _wrap(uint256 _amount) internal { IWETH(WNATIVE).deposit{ value: _amount }(); } function _unwrap(uint256 _amount) internal { IWETH(WNATIVE).withdraw(_amount); } /** * @notice Return tokens to user * @dev Pass address(0) for AVAX * @param _token address * @param _amount tokens to return * @param _to address where funds should be sent to */ function _returnTokensTo( address _token, uint256 _amount, address _to ) internal { if (address(this) != _to) { if (_token == NATIVE) { payable(_to).transfer(_amount); } else { IERC20(_token).safeTransfer(_to, _amount); } } } function _transferFrom(address token, address _from, address _to, uint _amount) internal { if (_from != address(this)) IERC20(token).safeTransferFrom(_from, _to, _amount); else IERC20(token).safeTransfer(_to, _amount); } // -- QUERIES -- /** * Query single adapter */ function queryAdapter( uint256 _amountIn, address _tokenIn, address _tokenOut, uint8 _index ) override external view returns (uint256) { IAdapter _adapter = IAdapter(ADAPTERS[_index]); uint256 amountOut = _adapter.query(_amountIn, _tokenIn, _tokenOut); return amountOut; } /** * Query specified adapters */ function queryNoSplit( uint256 _amountIn, address _tokenIn, address _tokenOut, uint8[] calldata _options ) override public view returns (Query memory) { Query memory bestQuery; for (uint8 i; i < _options.length; i++) { address _adapter = ADAPTERS[_options[i]]; uint256 amountOut = IAdapter(_adapter).query(_amountIn, _tokenIn, _tokenOut); if (i == 0 || amountOut > bestQuery.amountOut) { bestQuery = Query(_adapter, _tokenIn, _tokenOut, amountOut); } } return bestQuery; } /** * Query all adapters */ function queryNoSplit( uint256 _amountIn, address _tokenIn, address _tokenOut ) override public view returns (Query memory) { Query memory bestQuery; for (uint8 i; i < ADAPTERS.length; i++) { address _adapter = ADAPTERS[i]; uint256 amountOut = IAdapter(_adapter).query(_amountIn, _tokenIn, _tokenOut); if (i == 0 || amountOut > bestQuery.amountOut) { bestQuery = Query(_adapter, _tokenIn, _tokenOut, amountOut); } } return bestQuery; } /** * Return path with best returns between two tokens * Takes gas-cost into account */ function findBestPathWithGas( uint256 _amountIn, address _tokenIn, address _tokenOut, uint256 _maxSteps, uint256 _gasPrice ) override external view returns (FormattedOffer memory) { require(_maxSteps > 0 && _maxSteps < 5, "YakRouter: Invalid max-steps"); Offer memory queries = OfferUtils.newOffer(_amountIn, _tokenIn); uint256 gasPriceInExitTkn = _gasPrice > 0 ? getGasPriceInExitTkn(_gasPrice, _tokenOut) : 0; queries = _findBestPath(_amountIn, _tokenIn, _tokenOut, _maxSteps, queries, gasPriceInExitTkn); if (queries.adapters.length == 0) { queries.amounts = ""; queries.path = ""; } return queries.format(); } // Find the market price between gas-asset(native) and token-out and express gas price in token-out function getGasPriceInExitTkn(uint256 _gasPrice, address _tokenOut) internal view returns (uint256 price) { // Avoid low-liquidity price appreciation (https://github.com/yieldyak/yak-aggregator/issues/20) FormattedOffer memory gasQuery = findBestPath(1e18, WNATIVE, _tokenOut, 2); if (gasQuery.path.length != 0) { // Leave result in nWei to preserve precision for assets with low decimal places price = (gasQuery.amounts[gasQuery.amounts.length - 1] * _gasPrice) / 1e9; } } /** * Return path with best returns between two tokens */ function findBestPath( uint256 _amountIn, address _tokenIn, address _tokenOut, uint256 _maxSteps ) override public view returns (FormattedOffer memory) { require(_maxSteps > 0 && _maxSteps < 5, "YakRouter: Invalid max-steps"); Offer memory queries = OfferUtils.newOffer(_amountIn, _tokenIn); queries = _findBestPath(_amountIn, _tokenIn, _tokenOut, _maxSteps, queries, 0); // If no paths are found return empty struct if (queries.adapters.length == 0) { queries.amounts = ""; queries.path = ""; } return queries.format(); } function _findBestPath( uint256 _amountIn, address _tokenIn, address _tokenOut, uint256 _maxSteps, Offer memory _queries, uint256 _tknOutPriceNwei ) internal view returns (Offer memory) { Offer memory bestOption = _queries.clone(); uint256 bestAmountOut; uint256 gasEstimate; bool withGas = _tknOutPriceNwei != 0; // First check if there is a path directly from tokenIn to tokenOut Query memory queryDirect = queryNoSplit(_amountIn, _tokenIn, _tokenOut); if (queryDirect.amountOut != 0) { if (withGas) { gasEstimate = IAdapter(queryDirect.adapter).swapGasEstimate(); } bestOption.addToTail(queryDirect.amountOut, queryDirect.adapter, queryDirect.tokenOut, gasEstimate); bestAmountOut = queryDirect.amountOut; } // Only check the rest if they would go beyond step limit (Need at least 2 more steps) if (_maxSteps > 1 && _queries.adapters.length / 32 <= _maxSteps - 2) { // Check for paths that pass through trusted tokens for (uint256 i = 0; i < TRUSTED_TOKENS.length; i++) { if (_tokenIn == TRUSTED_TOKENS[i]) { continue; } // Loop through all adapters to find the best one for swapping tokenIn for one of the trusted tokens Query memory bestSwap = queryNoSplit(_amountIn, _tokenIn, TRUSTED_TOKENS[i]); if (bestSwap.amountOut == 0) { continue; } // Explore options that connect the current path to the tokenOut Offer memory newOffer = _queries.clone(); if (withGas) { gasEstimate = IAdapter(bestSwap.adapter).swapGasEstimate(); } newOffer.addToTail(bestSwap.amountOut, bestSwap.adapter, bestSwap.tokenOut, gasEstimate); newOffer = _findBestPath( bestSwap.amountOut, TRUSTED_TOKENS[i], _tokenOut, _maxSteps, newOffer, _tknOutPriceNwei ); // Recursive step address tokenOut = newOffer.getTokenOut(); uint256 amountOut = newOffer.getAmountOut(); // Check that the last token in the path is the tokenOut and update the new best option if neccesary if (_tokenOut == tokenOut && amountOut > bestAmountOut) { if (newOffer.gasEstimate > bestOption.gasEstimate) { uint256 gasCostDiff = (_tknOutPriceNwei * (newOffer.gasEstimate - bestOption.gasEstimate)) / 1e9; uint256 priceDiff = amountOut - bestAmountOut; if (gasCostDiff > priceDiff) { continue; } } bestAmountOut = amountOut; bestOption = newOffer; } } } return bestOption; } // -- SWAPPERS -- function _swapNoSplit( Trade calldata _trade, address _from, address _to, uint256 _fee ) internal returns (uint256) { uint256[] memory amounts = new uint256[](_trade.path.length); if (_fee > 0 || MIN_FEE > 0) { // Transfer fees to the claimer account and decrease initial amount amounts[0] = _applyFee(_trade.amountIn, _fee); _transferFrom(_trade.path[0], _from, FEE_CLAIMER, _trade.amountIn - amounts[0]); } else { amounts[0] = _trade.amountIn; } _transferFrom(_trade.path[0], _from, _trade.adapters[0], amounts[0]); // Get amounts that will be swapped for (uint256 i = 0; i < _trade.adapters.length; i++) { amounts[i + 1] = IAdapter(_trade.adapters[i]).query(amounts[i], _trade.path[i], _trade.path[i + 1]); } require(amounts[amounts.length - 1] >= _trade.amountOut, "YakRouter: Insufficient output amount"); for (uint256 i = 0; i < _trade.adapters.length; i++) { // All adapters should transfer output token to the following target // All targets are the adapters, expect for the last swap where tokens are sent out address targetAddress = i < _trade.adapters.length - 1 ? _trade.adapters[i + 1] : _to; IAdapter(_trade.adapters[i]).swap( amounts[i], amounts[i + 1], _trade.path[i], _trade.path[i + 1], targetAddress ); } emit YakSwap(_trade.path[0], _trade.path[_trade.path.length - 1], _trade.amountIn, amounts[amounts.length - 1]); return amounts[amounts.length - 1]; } function swapNoSplit( Trade calldata _trade, address _to, uint256 _fee ) override public { _swapNoSplit(_trade, msg.sender, _to, _fee); } function swapNoSplitFromAVAX( Trade calldata _trade, address _to, uint256 _fee ) override external payable { require(_trade.path[0] == WNATIVE, "YakRouter: Path needs to begin with WAVAX"); _wrap(_trade.amountIn); _swapNoSplit(_trade, address(this), _to, _fee); } function swapNoSplitToAVAX( Trade calldata _trade, address _to, uint256 _fee ) override public { require(_trade.path[_trade.path.length - 1] == WNATIVE, "YakRouter: Path needs to end with WAVAX"); uint256 returnAmount = _swapNoSplit(_trade, msg.sender, address(this), _fee); _unwrap(returnAmount); _returnTokensTo(NATIVE, returnAmount, _to); } /** * Swap token to token without the need to approve the first token */ function swapNoSplitWithPermit( Trade calldata _trade, address _to, uint256 _fee, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) override external { IERC20(_trade.path[0]).permit(msg.sender, address(this), _trade.amountIn, _deadline, _v, _r, _s); swapNoSplit(_trade, _to, _fee); } /** * Swap token to AVAX without the need to approve the first token */ function swapNoSplitToAVAXWithPermit( Trade calldata _trade, address _to, uint256 _fee, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) override external { IERC20(_trade.path[0]).permit(msg.sender, address(this), _trade.amountIn, _deadline, _v, _r, _s); swapNoSplitToAVAX(_trade, _to, _fee); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ```solidity * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ```solidity * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules} * to enforce additional security measures for this role. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(account), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (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; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IAdapter { function name() external view returns (string memory); function swapGasEstimate() external view returns (uint256); function swap( uint256, uint256, address, address, address ) external; function query( uint256, address, address ) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC20 { event Approval(address, address, uint256); event Transfer(address, address, uint256); function name() external view returns (string memory); function decimals() external view returns (uint8); function transferFrom( address, address, uint256 ) external returns (bool); function allowance(address, address) external view returns (uint256); function approve(address, uint256) external returns (bool); function transfer(address, uint256) external returns (bool); function balanceOf(address) external view returns (uint256); function nonces(address) external view returns (uint256); // Only tokens that support permit function permit( address, address, uint256, uint256, uint8, bytes32, bytes32 ) external; // Only tokens that support permit function swap(address, uint256) external; // Only Avalanche bridge tokens function swapSupply(address) external view returns (uint256); // Only Avalanche bridge tokens function totalSupply() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20.sol"; interface IWETH is IERC20 { function withdraw(uint256 amount) external; function deposit() external payable; }
// ╟╗ ╔╬ // ╞╬╬ ╬╠╬ // ╔╣╬╬╬ ╠╠╠╠╦ // ╬╬╬╬╬╩ ╘╠╠╠╠╬ // ║╬╬╬╬╬ ╘╠╠╠╠╬ // ╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╒╬╬╬╬╬╬╬╜ ╠╠╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╬╬╬╬╬╬╬╬╠╠╠╠╠╠╠╠ // ╙╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╕ ╬╬╬╬╬╬╬╜ ╣╠╠╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╬╬╬╬╬╬╬╬╬╠╠╠╠╠╠╠╩ // ╙╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╔╬╬╬╬╬╬╬ ╔╠╠╠╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╣╬╬╬╬╬╬╬╬╬╬╬╠╠╠╠╝╙ // ╘╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╒╠╠╠╬╠╬╩╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╣╬╬╬╬╬╬╬╙ // ╣╬╬╬╬╬╬╬╬╬╬╠╣ ╣╬╠╠╠╬╩ ╚╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╬╬╬╬╬╬╬ // ╣╬╬╬╬╬╬╬╬╬╣ ╣╬╠╠╠╬╬ ╣╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╬╬╬╬╬╬╬ // ╟╬╬╬╬╬╬╬╩ ╬╬╠╠╠╠╬╬╬╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╠╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╒╬╬╠╠╬╠╠╬╬╬╬╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╣╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╬╬╬╠╠╠╠╝╝╝╝╝╝╝╠╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╚╬╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╣╬╬╬╬╠╠╩ ╘╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╙╬╬╬╬╬╬╬╬ // // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; struct Query { address adapter; address tokenIn; address tokenOut; uint256 amountOut; } struct Offer { bytes amounts; bytes adapters; bytes path; uint256 gasEstimate; } struct FormattedOffer { uint256[] amounts; address[] adapters; address[] path; uint256 gasEstimate; } struct Trade { uint256 amountIn; uint256 amountOut; address[] path; address[] adapters; } interface IYakRouter { event UpdatedTrustedTokens(address[] _newTrustedTokens); event UpdatedAdapters(address[] _newAdapters); event UpdatedMinFee(uint256 _oldMinFee, uint256 _newMinFee); event UpdatedFeeClaimer(address _oldFeeClaimer, address _newFeeClaimer); event YakSwap(address indexed _tokenIn, address indexed _tokenOut, uint256 _amountIn, uint256 _amountOut); // admin function setTrustedTokens(address[] memory _trustedTokens) external; function setAdapters(address[] memory _adapters) external; function setFeeClaimer(address _claimer) external; function setMinFee(uint256 _fee) external; // misc function trustedTokensCount() external view returns (uint256); function adaptersCount() external view returns (uint256); // query function queryAdapter( uint256 _amountIn, address _tokenIn, address _tokenOut, uint8 _index ) external returns (uint256); function queryNoSplit( uint256 _amountIn, address _tokenIn, address _tokenOut, uint8[] calldata _options ) external view returns (Query memory); function queryNoSplit( uint256 _amountIn, address _tokenIn, address _tokenOut ) external view returns (Query memory); function findBestPathWithGas( uint256 _amountIn, address _tokenIn, address _tokenOut, uint256 _maxSteps, uint256 _gasPrice ) external view returns (FormattedOffer memory); function findBestPath( uint256 _amountIn, address _tokenIn, address _tokenOut, uint256 _maxSteps ) external view returns (FormattedOffer memory); // swap function swapNoSplit( Trade calldata _trade, address _to, uint256 _fee ) external; function swapNoSplitFromAVAX( Trade calldata _trade, address _to, uint256 _fee ) external payable; function swapNoSplitToAVAX( Trade calldata _trade, address _to, uint256 _fee ) external; function swapNoSplitWithPermit( Trade calldata _trade, address _to, uint256 _fee, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) external; function swapNoSplitToAVAXWithPermit( Trade calldata _trade, address _to, uint256 _fee, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/AccessControl.sol"; /** * @dev Contract module which extends the basic access control mechanism of Ownable * to include many maintainers, whom only the owner (DEFAULT_ADMIN_ROLE) may add and * remove. * * 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 this modifier: * `onlyMaintainer`, which can be applied to your functions to restrict their use to * the accounts with the role of maintainer. */ abstract contract Maintainable is Context, AccessControl { bytes32 public constant MAINTAINER_ROLE = keccak256("MAINTAINER_ROLE"); constructor() { address msgSender = _msgSender(); // members of the DEFAULT_ADMIN_ROLE alone may revoke and grant role membership _setupRole(DEFAULT_ADMIN_ROLE, msgSender); _setupRole(MAINTAINER_ROLE, msgSender); } function addMaintainer(address addedMaintainer) public virtual { grantRole(MAINTAINER_ROLE, addedMaintainer); } function removeMaintainer(address removedMaintainer) public virtual { revokeRole(MAINTAINER_ROLE, removedMaintainer); } function renounceRole(bytes32 role) public virtual { address msgSender = _msgSender(); renounceRole(role, msgSender); } function transferOwnership(address newOwner) public virtual { address msgSender = _msgSender(); grantRole(DEFAULT_ADMIN_ROLE, newOwner); renounceRole(DEFAULT_ADMIN_ROLE, msgSender); } modifier onlyMaintainer() { address msgSender = _msgSender(); require(hasRole(MAINTAINER_ROLE, msgSender), "Maintainable: Caller is not a maintainer"); _; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; import "./SafeERC20.sol"; import "./Maintainable.sol"; abstract contract Recoverable is Maintainable { using SafeERC20 for IERC20; event Recovered( address indexed _asset, uint amount ); /** * @notice Recover ERC20 from contract * @param _tokenAddress token address * @param _tokenAmount amount to recover */ function recoverERC20(address _tokenAddress, uint _tokenAmount) external onlyMaintainer { require(_tokenAmount > 0, "Nothing to recover"); IERC20(_tokenAddress).safeTransfer(msg.sender, _tokenAmount); emit Recovered(_tokenAddress, _tokenAmount); } /** * @notice Recover native asset from contract * @param _amount amount */ function recoverNative(uint _amount) external onlyMaintainer { require(_amount > 0, "Nothing to recover"); payable(msg.sender).transfer(_amount); emit Recovered(address(0), _amount); } }
// This is a simplified version of OpenZepplin's SafeERC20 library // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma experimental ABIEncoderV2; import "../interface/IERC20.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 ERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } 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' // solhint-disable-next-line max-line-length 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 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. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; library TypeConversion { function toBytes12(address x) internal pure returns (bytes12 y) { assembly { y := x } } function toBytes32(address x) internal pure returns (bytes32 y) { assembly { y := x } } function toAddress(bytes32 x) internal pure returns (address y) { assembly { y := x } } function toBytes(address x) internal pure returns (bytes memory y) { y = new bytes(32); assembly { mstore(add(y, 32), x) } } function toBytes(bytes32 x) internal pure returns (bytes memory y) { y = new bytes(32); assembly { mstore(add(y, 32), x) } } function toBytes(uint x) internal pure returns (bytes memory y) { y = new bytes(32); assembly { mstore(add(y, 32), x) } } function toAddress( bytes memory x, uint offset ) internal pure returns (address y) { assembly { y := mload(add(x, offset)) } } function toUint( bytes memory x, uint offset ) internal pure returns (uint y) { assembly { y := mload(add(x, offset)) } } function toBytes12( bytes memory x, uint offset ) internal pure returns (bytes12 y) { assembly { y := mload(add(x, offset)) } } function toBytes32( bytes memory x, uint offset ) internal pure returns (bytes32 y) { assembly { y := mload(add(x, offset)) } } function toAddresses( bytes memory xs ) internal pure returns (address[] memory ys) { ys = new address[](xs.length/32); for (uint i=0; i < xs.length/32; i++) { ys[i] = toAddress(xs, i*32 + 32); } } function toUints( bytes memory xs ) internal pure returns (uint[] memory ys) { ys = new uint[](xs.length/32); for (uint i=0; i < xs.length/32; i++) { ys[i] = toUint(xs, i*32 + 32); } } function toBytes32s( bytes memory xs ) internal pure returns (bytes32[] memory ys) { ys = new bytes32[](xs.length/32); for (uint i=0; i < xs.length/32; i++) { ys[i] = toBytes32(xs, i*32 + 32); } } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity >=0.8.4; import { Offer, FormattedOffer } from "../interface/IYakRouter.sol"; import "./TypeConversion.sol"; library OfferUtils { using TypeConversion for address; using TypeConversion for uint256; using TypeConversion for bytes; function newOffer( uint _amountIn, address _tokenIn ) internal pure returns (Offer memory offer) { offer.amounts = _amountIn.toBytes(); offer.path = _tokenIn.toBytes(); } /** * Makes a deep copy of Offer struct */ function clone(Offer memory _queries) internal pure returns (Offer memory) { return Offer(_queries.amounts, _queries.adapters, _queries.path, _queries.gasEstimate); } /** * Appends new elements to the end of Offer struct */ function addToTail( Offer memory _queries, uint256 _amount, address _adapter, address _tokenOut, uint256 _gasEstimate ) internal pure { _queries.path = bytes.concat(_queries.path, _tokenOut.toBytes()); _queries.adapters = bytes.concat(_queries.adapters, _adapter.toBytes()); _queries.amounts = bytes.concat(_queries.amounts, _amount.toBytes()); _queries.gasEstimate += _gasEstimate; } /** * Formats elements in the Offer object from byte-arrays to integers and addresses */ function format(Offer memory _queries) internal pure returns (FormattedOffer memory) { return FormattedOffer( _queries.amounts.toUints(), _queries.adapters.toAddresses(), _queries.path.toAddresses(), _queries.gasEstimate ); } function getTokenOut( Offer memory _offer ) internal pure returns (address tokenOut) { tokenOut = _offer.path.toAddress(_offer.path.length); // Last 32 bytes } function getAmountOut( Offer memory _offer ) internal pure returns (uint amountOut) { amountOut = _offer.amounts.toUint(_offer.path.length); // Last 32 bytes } } library FormattedOfferUtils { using TypeConversion for address; using TypeConversion for uint256; using TypeConversion for bytes; /** * Appends new elements to the end of FormattedOffer */ function addToTail( FormattedOffer memory offer, uint256 amountOut, address wrapper, address tokenOut, uint256 gasEstimate ) internal pure { offer.amounts = bytes.concat(abi.encodePacked(offer.amounts), amountOut.toBytes()).toUints(); offer.adapters = bytes.concat(abi.encodePacked(offer.adapters), wrapper.toBytes()).toAddresses(); offer.path = bytes.concat(abi.encodePacked(offer.path), tokenOut.toBytes()).toAddresses(); offer.gasEstimate += gasEstimate; } /** * Appends new elements to the beginning of FormattedOffer */ function addToHead( FormattedOffer memory offer, uint256 amountOut, address wrapper, address tokenOut, uint256 gasEstimate ) internal pure { offer.amounts = bytes.concat(amountOut.toBytes(), abi.encodePacked(offer.amounts)).toUints(); offer.adapters = bytes.concat(wrapper.toBytes(), abi.encodePacked(offer.adapters)).toAddresses(); offer.path = bytes.concat(tokenOut.toBytes(), abi.encodePacked(offer.path)).toAddresses(); offer.gasEstimate += gasEstimate; } function getAmountOut(FormattedOffer memory offer) internal pure returns (uint256) { return offer.amounts[offer.amounts.length - 1]; } }
{ "optimizer": { "enabled": true, "runs": 1000 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[]","name":"_adapters","type":"address[]"},{"internalType":"address[]","name":"_trustedTokens","type":"address[]"},{"internalType":"address","name":"_feeClaimer","type":"address"},{"internalType":"address","name":"_wrapped_native","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"_newAdapters","type":"address[]"}],"name":"UpdatedAdapters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_oldFeeClaimer","type":"address"},{"indexed":false,"internalType":"address","name":"_newFeeClaimer","type":"address"}],"name":"UpdatedFeeClaimer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_oldMinFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newMinFee","type":"uint256"}],"name":"UpdatedMinFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"_newTrustedTokens","type":"address[]"}],"name":"UpdatedTrustedTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"_tokenOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amountOut","type":"uint256"}],"name":"YakSwap","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ADAPTERS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_CLAIMER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAINTAINER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NATIVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"TRUSTED_TOKENS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WNATIVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adaptersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addedMaintainer","type":"address"}],"name":"addMaintainer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_maxSteps","type":"uint256"}],"name":"findBestPath","outputs":[{"components":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address[]","name":"adapters","type":"address[]"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"gasEstimate","type":"uint256"}],"internalType":"struct FormattedOffer","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint256","name":"_maxSteps","type":"uint256"},{"internalType":"uint256","name":"_gasPrice","type":"uint256"}],"name":"findBestPathWithGas","outputs":[{"components":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address[]","name":"adapters","type":"address[]"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"gasEstimate","type":"uint256"}],"internalType":"struct FormattedOffer","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint8","name":"_index","type":"uint8"}],"name":"queryAdapter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint8[]","name":"_options","type":"uint8[]"}],"name":"queryNoSplit","outputs":[{"components":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"internalType":"struct Query","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"address","name":"_tokenOut","type":"address"}],"name":"queryNoSplit","outputs":[{"components":[{"internalType":"address","name":"adapter","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"internalType":"struct Query","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"recoverNative","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"removedMaintainer","type":"address"}],"name":"removeMaintainer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_adapters","type":"address[]"}],"name":"setAdapters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wnative","type":"address"}],"name":"setAllowanceForWrapping","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_claimer","type":"address"}],"name":"setFeeClaimer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setMinFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_trustedTokens","type":"address[]"}],"name":"setTrustedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address[]","name":"adapters","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"swapNoSplit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address[]","name":"adapters","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"swapNoSplitFromAVAX","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address[]","name":"adapters","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"swapNoSplitToAVAX","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address[]","name":"adapters","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"swapNoSplitToAVAXWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address[]","name":"adapters","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"uint256","name":"_deadline","type":"uint256"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"swapNoSplitWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"trustedTokensCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60a0604052600060015534801561001557600080fd5b50604051614490380380614490833981016040819052610034916107dd565b336100406000826100a4565b61006a7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab95826100a4565b50610074816100b2565b61007d83610138565b610086826101f2565b61008f846102c7565b6001600160a01b031660805250610924915050565b6100ae828261037c565b5050565b336000818152600080516020614450833981519152602052604090205460ff166101225760405162461bcd60e51b8152602060048201526028602482015260008051602061447083398151915260448201526734b73a30b4b732b960c11b60648201526084015b60405180910390fd5b6100ae6001600160a01b0383168360001961041a565b336000818152600080516020614450833981519152602052604090205460ff166101a35760405162461bcd60e51b8152602060048201526028602482015260008051602061447083398151915260448201526734b73a30b4b732b960c11b6064820152608401610119565b7f658ff1688002926d8f426cb10c052ec29003f50042df9652d8613484c1a58647826040516101d29190610867565b60405180910390a181516101ed90600390602085019061068b565b505050565b336000818152600080516020614450833981519152602052604090205460ff1661025d5760405162461bcd60e51b8152602060048201526028602482015260008051602061447083398151915260448201526734b73a30b4b732b960c11b6064820152608401610119565b600254604080516001600160a01b03928316815291841660208301527fb2c853ac4d80d18d058c43d8018d077a036e542a79acae1647f5ad2a8c76f4e2910160405180910390a150600280546001600160a01b0319166001600160a01b0392909216919091179055565b336000818152600080516020614450833981519152602052604090205460ff166103325760405162461bcd60e51b8152602060048201526028602482015260008051602061447083398151915260448201526734b73a30b4b732b960c11b6064820152608401610119565b7febf7325f48e05e5e38809c69f8b02a7c907ed31d8768e6c2d841b1296a9225fe826040516103619190610867565b60405180910390a181516101ed90600490602085019061068b565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166100ae576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556103d63390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b8015806104945750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561046e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049291906108b3565b155b6105065760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610119565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526101ed91859161055c16565b600080836001600160a01b03168360405161057791906108cc565b6000604051808303816000865af19150503d80600081146105b4576040519150601f19603f3d011682016040523d82523d6000602084013e6105b9565b606091505b50915091508161060b5760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65646044820152606401610119565b805115610685578080602001905181019061062691906108fb565b6106855760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610119565b50505050565b8280548282559060005260206000209081019282156106e0579160200282015b828111156106e057825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906106ab565b506106ec9291506106f0565b5090565b5b808211156106ec57600081556001016106f1565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b038116811461073257600080fd5b919050565b600082601f83011261074857600080fd5b81516001600160401b0381111561076157610761610705565b604051600582901b90603f8201601f191681016001600160401b038111828210171561078f5761078f610705565b6040529182526020818501810192908101868411156107ad57600080fd5b6020860192505b838310156107d3576107c58361071b565b8152602092830192016107b4565b5095945050505050565b600080600080608085870312156107f357600080fd5b84516001600160401b0381111561080957600080fd5b61081587828801610737565b602087015190955090506001600160401b0381111561083357600080fd5b61083f87828801610737565b93505061084e6040860161071b565b915061085c6060860161071b565b905092959194509250565b602080825282518282018190526000918401906040840190835b818110156108a85783516001600160a01b0316835260209384019390920191600101610881565b509095945050505050565b6000602082840312156108c557600080fd5b5051919050565b6000825160005b818110156108ed57602081860181015185830152016108d3565b506000920191825250919050565b60006020828403121561090d57600080fd5b8151801515811461091d57600080fd5b9392505050565b608051613aee610962600039600081816106f2015281816118530152818161198001528181611ac9015281816129420152612a130152613aee6000f3fe6080604052600436106102a35760003560e01c80638bb9c5bf1161016e578063c8a3a5c6116100cb578063dede7f151161007f578063f2fde38b11610064578063f2fde38b1461080a578063f87422541461082a578063fe38c5e61461085e57600080fd5b8063dede7f15146107ca578063f0350382146107ea57600080fd5b8063d73792a9116100b0578063d73792a914610774578063d8baf7cf1461078a578063dd8544b3146107aa57600080fd5b8063c8a3a5c614610734578063d547741f1461075457600080fd5b8063a217fddf11610122578063aede369311610107578063aede3693146106c0578063b381cf40146106e0578063c3accd481461071457600080fd5b8063a217fddf14610655578063a3f4df7e1461066a57600080fd5b806392f5d88a1161015357806392f5d88a146105ad578063952e901214610620578063a0cf0aea1461064057600080fd5b80638bb9c5bf1461054957806391d148541461056957600080fd5b80634c09cf4e1161021c57806376c7a3c7116101d05780637c7a561b116101b55780637c7a561b146104f4578063809356aa146105095780638980f11f1461052957600080fd5b806376c7a3c7146104c957806376ebe69c146104df57600080fd5b80636b453c1f116102015780636b453c1f146104695780636bf2df861461048957806375d19947146104a957600080fd5b80634c09cf4e1461042957806352a52ab01461044957600080fd5b8063248a9ca31161027357806331ac99201161025857806331ac9920146103c957806336568abe146103e95780633a9a40811461040957600080fd5b8063248a9ca31461036b5780632f2ff15d146103a957600080fd5b8062b99e36146102af57806301ffc9a7146102ec578063061b15e71461031c5780631e189dc21461034957600080fd5b366102aa57005b600080fd5b3480156102bb57600080fd5b506002546102cf906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102f857600080fd5b5061030c610307366004613298565b610871565b60405190151581526020016102e3565b34801561032857600080fd5b5061033c6103373660046132de565b6108da565b6040516102e39190613371565b34801561035557600080fd5b50610369610364366004613431565b6109e4565b005b34801561037757600080fd5b5061039b6103863660046134b7565b60009081526020819052604090206001015490565b6040519081526020016102e3565b3480156103b557600080fd5b506103696103c43660046134d0565b610ab1565b3480156103d557600080fd5b506103696103e43660046134b7565b610adb565b3480156103f557600080fd5b506103696104043660046134d0565b610bac565b34801561041557600080fd5b50610369610424366004613512565b610c38565b34801561043557600080fd5b5061033c6104443660046135d7565b610d11565b34801561045557600080fd5b506102cf6104643660046134b7565b610df9565b34801561047557600080fd5b5061036961048436600461361b565b610e23565b34801561049557600080fd5b506103696104a4366004613636565b610e50565b3480156104b557600080fd5b506103696104c4366004613431565b610e62565b3480156104d557600080fd5b5061039b60015481565b3480156104eb57600080fd5b5060035461039b565b34801561050057600080fd5b5060045461039b565b34801561051557600080fd5b5061039b61052436600461368e565b610f26565b34801561053557600080fd5b506103696105443660046136db565b610fd2565b34801561055557600080fd5b506103696105643660046134b7565b61110d565b34801561057557600080fd5b5061030c6105843660046134d0565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b3480156105b957600080fd5b506105cd6105c8366004613705565b611118565b6040516102e3919060006080820190506001600160a01b0383511682526001600160a01b0360208401511660208301526001600160a01b0360408401511660408301526060830151606083015292915050565b34801561062c57600080fd5b506102cf61063b3660046134b7565b6112b0565b34801561064c57600080fd5b506102cf600081565b34801561066157600080fd5b5061039b600081565b34801561067657600080fd5b506106b36040518060400160405280600981526020017f59616b526f75746572000000000000000000000000000000000000000000000081525081565b6040516102e391906137c9565b3480156106cc57600080fd5b506103696106db3660046134b7565b6112c0565b3480156106ec57600080fd5b506102cf7f000000000000000000000000000000000000000000000000000000000000000081565b34801561072057600080fd5b5061036961072f36600461361b565b611407565b34801561074057600080fd5b5061036961074f366004613512565b61150d565b34801561076057600080fd5b5061036961076f3660046134d0565b6115e6565b34801561078057600080fd5b5061039b61271081565b34801561079657600080fd5b506103696107a536600461361b565b61160b565b3480156107b657600080fd5b506103696107c536600461361b565b611635565b3480156107d657600080fd5b506105cd6107e53660046137fc565b6116da565b3480156107f657600080fd5b50610369610805366004613636565b611849565b34801561081657600080fd5b5061036961082536600461361b565b61195f565b34801561083657600080fd5b5061039b7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab9581565b61036961086c366004613636565b611976565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806108d457507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b6109056040518060800160405280606081526020016060815260200160608152602001600081525090565b6000831180156109155750600583105b6109665760405162461bcd60e51b815260206004820152601c60248201527f59616b526f757465723a20496e76616c6964206d61782d73746570730000000060448201526064015b60405180910390fd5b60006109728787611a65565b9050600080841161098457600061098e565b61098e8487611ab8565b905061099e888888888686611b4d565b91508160200151516000036109cf576040805160208082018352600080835291855282519081018352908152908301525b6109d882611e87565b98975050505050505050565b6109f16040880188613838565b6000818110610a0257610a02613889565b9050602002016020810190610a17919061361b565b60405163d505accf60e01b8152336004820152306024820152883560448201526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b03919091169063d505accf9060e401600060405180830381600087803b158015610a8557600080fd5b505af1158015610a99573d6000803e3d6000fd5b50505050610aa8878787611849565b50505050505050565b600082815260208190526040902060010154610acc81611f02565b610ad68383611f0c565b505050565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff16610b6a5760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b60015460408051918252602082018490527f4bb8a6184424e4bb853a4836042f5a726e4e710873989bfc6abdab19966f5b70910160405180910390a150600155565b6001600160a01b0381163314610c2a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161095d565b610c348282611faa565b5050565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff16610cc75760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b7febf7325f48e05e5e38809c69f8b02a7c907ed31d8768e6c2d841b1296a9225fe82604051610cf6919061389f565b60405180910390a18151610ad6906004906020850190613211565b610d3c6040518060800160405280606081526020016060815260200160608152602001600081525090565b600082118015610d4c5750600582105b610d985760405162461bcd60e51b815260206004820152601c60248201527f59616b526f757465723a20496e76616c6964206d61782d737465707300000000604482015260640161095d565b6000610da48686611a65565b9050610db586868686856000611b4d565b9050806020015151600003610de6576040805160208082018352600080835291845282519081018352908152908201525b610def81611e87565b9695505050505050565b60038181548110610e0957600080fd5b6000918252602090912001546001600160a01b0316905081565b610e4d7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab9582610ab1565b50565b610e5c83338484612029565b50505050565b610e6f6040880188613838565b6000818110610e8057610e80613889565b9050602002016020810190610e95919061361b565b60405163d505accf60e01b8152336004820152306024820152883560448201526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b03919091169063d505accf9060e401600060405180830381600087803b158015610f0357600080fd5b505af1158015610f17573d6000803e3d6000fd5b50505050610aa8878787610e50565b60008060048360ff1681548110610f3f57610f3f613889565b60009182526020822001546040516377ccc49d60e11b8152600481018990526001600160a01b03888116602483015287811660448301529091169250829063ef99893a90606401602060405180830381865afa158015610fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc791906138eb565b979650505050505050565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff166110615760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b600082116110b15760405162461bcd60e51b815260206004820152601260248201527f4e6f7468696e6720746f207265636f7665720000000000000000000000000000604482015260640161095d565b6110c56001600160a01b0384163384612734565b826001600160a01b03167f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288360405161110091815260200190565b60405180910390a2505050565b33610c348282610bac565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260005b60ff81168411156112a5576000600486868460ff1681811061118757611187613889565b905060200201602081019061119c9190613904565b60ff16815481106111af576111af613889565b60009182526020822001546040516377ccc49d60e11b8152600481018c90526001600160a01b038b811660248301528a811660448301529091169250829063ef99893a90606401602060405180830381865afa158015611213573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123791906138eb565b905060ff8316158061124c5750836060015181115b15611290576040518060800160405280836001600160a01b031681526020018a6001600160a01b03168152602001896001600160a01b031681526020018281525093505b5050808061129d90613935565b915050611163565b509695505050505050565b60048181548110610e0957600080fd5b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff1661134f5760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b6000821161139f5760405162461bcd60e51b815260206004820152601260248201527f4e6f7468696e6720746f207265636f7665720000000000000000000000000000604482015260640161095d565b604051339083156108fc029084906000818181858888f193505050501580156113cc573d6000803e3d6000fd5b506040518281526000907f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa289060200160405180910390a25050565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff166114965760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b600254604080516001600160a01b03928316815291841660208301527fb2c853ac4d80d18d058c43d8018d077a036e542a79acae1647f5ad2a8c76f4e2910160405180910390a1506002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff1661159c5760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b7f658ff1688002926d8f426cb10c052ec29003f50042df9652d8613484c1a58647826040516115cb919061389f565b60405180910390a18151610ad6906003906020850190613211565b60008281526020819052604090206001015461160181611f02565b610ad68383611faa565b610e4d7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab95826115e6565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff166116c45760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b610c346001600160a01b038316836000196127c5565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260005b60045460ff8216101561184057600060048260ff168154811061174a5761174a613889565b60009182526020822001546040516377ccc49d60e11b8152600481018a90526001600160a01b03898116602483015288811660448301529091169250829063ef99893a90606401602060405180830381865afa1580156117ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d291906138eb565b905060ff831615806117e75750836060015181115b1561182b576040518060800160405280836001600160a01b03168152602001886001600160a01b03168152602001876001600160a01b031681526020018281525093505b5050808061183890613935565b915050611725565b50949350505050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166118806040850185613838565b600161188f6040880188613838565b61189a929150613954565b8181106118a9576118a9613889565b90506020020160208101906118be919061361b565b6001600160a01b03161461193a5760405162461bcd60e51b815260206004820152602760248201527f59616b526f757465723a2050617468206e6565647320746f20656e642077697460448201527f6820574156415800000000000000000000000000000000000000000000000000606482015260840161095d565b600061194884333085612029565b905061195381612913565b610e5c600082856129a9565b3361196b600083610ab1565b610c34600082610bac565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166119ad6040850185613838565b60008181106119be576119be613889565b90506020020160208101906119d3919061361b565b6001600160a01b031614611a4f5760405162461bcd60e51b815260206004820152602960248201527f59616b526f757465723a2050617468206e6565647320746f20626567696e207760448201527f6974682057415641580000000000000000000000000000000000000000000000606482015260840161095d565b611a598335612a11565b610e5c83308484612029565b611a906040518060800160405280606081526020016060815260200160608152602001600081525090565b611a9983612a88565b8152611aad6001600160a01b038316612a88565b604082015292915050565b600080611af0670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000000856002610d11565b9050806040015151600014611b465780518051633b9aca00918691611b1790600190613954565b81518110611b2757611b27613889565b6020026020010151611b399190613967565b611b43919061397e565b91505b5092915050565b611b786040518060800160405280606081526020016060815260200160608152602001600081525090565b6000611b8384612ab2565b905060008084151581611b978c8c8c6116da565b90508060600151600014611c36578115611c145780600001516001600160a01b03166369cff80d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1191906138eb565b92505b606081015181516040830151611c2e928892909187612b15565b806060015193505b600189118015611c615750611c4c60028a613954565b6020896020015151611c5e919061397e565b11155b15611e775760005b600354811015611e755760038181548110611c8657611c86613889565b6000918252602090912001546001600160a01b038d8116911614611e6d576000611cd88e8e60038581548110611cbe57611cbe613889565b6000918252602090912001546001600160a01b03166116da565b90508060600151600003611cec5750611e6d565b6000611cf78b612ab2565b90508415611d685781600001516001600160a01b03166369cff80d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6591906138eb565b95505b606082015182516040840151611d8292849290918a612b15565b611dbb826060015160038581548110611d9d57611d9d613889565b6000918252602090912001546001600160a01b03168f8f858f611b4d565b90506000611dc882612bd9565b90506000611dd583612bec565b9050816001600160a01b03168f6001600160a01b0316148015611df757508881115b15611e6857896060015183606001511115611e61576000633b9aca008b606001518560600151611e279190613954565b611e31908f613967565b611e3b919061397e565b90506000611e498b84613954565b905080821115611e5e57505050505050611e6d565b50505b8098508299505b505050505b600101611c69565b505b50929a9950505050505050505050565b611eb26040518060800160405280606081526020016060815260200160608152602001600081525090565b6040518060800160405280611eca8460000151612c01565b8152602001611edc8460200151612cb7565b8152602001611eee8460400151612cb7565b815260200183606001518152509050919050565b610e4d8133612d64565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610c34576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055611f663390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610c34576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000806120396040870187613838565b905067ffffffffffffffff811115612053576120536134fc565b60405190808252806020026020018201604052801561207c578160200160208202803683370190505b509050600083118061209057506000600154115b15612137576120a0863584612dd7565b816000815181106120b3576120b3613889565b60209081029190910101526121326120ce6040880188613838565b60008181106120df576120df613889565b90506020020160208101906120f4919061361b565b600254835188916001600160a01b031690859060009061211657612116613889565b60200260200101518a6000013561212d9190613954565b612e53565b61215c565b85600001358160008151811061214f5761214f613889565b6020026020010181815250505b6121e661216c6040880188613838565b600081811061217d5761217d613889565b9050602002016020810190612192919061361b565b866121a060608a018a613838565b60008181106121b1576121b1613889565b90506020020160208101906121c6919061361b565b846000815181106121d9576121d9613889565b6020026020010151612e53565b60005b6121f66060880188613838565b905081101561236f5761220c6060880188613838565b8281811061221c5761221c613889565b9050602002016020810190612231919061361b565b6001600160a01b031663ef99893a83838151811061225157612251613889565b60200260200101518980604001906122699190613838565b8581811061227957612279613889565b905060200201602081019061228e919061361b565b61229b60408c018c613838565b6122a68760016139a0565b8181106122b5576122b5613889565b90506020020160208101906122ca919061361b565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b039182166024840152166044820152606401602060405180830381865afa15801561231c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234091906138eb565b8261234c8360016139a0565b8151811061235c5761235c613889565b60209081029190910101526001016121e9565b50856020013581600183516123849190613954565b8151811061239457612394613889565b602002602001015110156124105760405162461bcd60e51b815260206004820152602560248201527f59616b526f757465723a20496e73756666696369656e74206f7574707574206160448201527f6d6f756e74000000000000000000000000000000000000000000000000000000606482015260840161095d565b60005b6124206060880188613838565b9050811015612605576000600161243a60608a018a613838565b612445929150613954565b8210612451578561248d565b61245e6060890189613838565b6124698460016139a0565b81811061247857612478613889565b905060200201602081019061248d919061361b565b905061249c6060890189613838565b838181106124ac576124ac613889565b90506020020160208101906124c1919061361b565b6001600160a01b031663eab90da68484815181106124e1576124e1613889565b6020026020010151858560016124f791906139a0565b8151811061250757612507613889565b60200260200101518b806040019061251f9190613838565b8781811061252f5761252f613889565b9050602002016020810190612544919061361b565b61255160408e018e613838565b61255c8960016139a0565b81811061256b5761256b613889565b9050602002016020810190612580919061361b565b6040516001600160e01b031960e087901b168152600481019490945260248401929092526001600160a01b03908116604484015290811660648301528416608482015260a401600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b505060019093019250612413915050565b506126136040870187613838565b600161262260408a018a613838565b61262d929150613954565b81811061263c5761263c613889565b9050602002016020810190612651919061361b565b6001600160a01b03166126676040880188613838565b600081811061267857612678613889565b905060200201602081019061268d919061361b565b6001600160a01b03167f9fc8352e52998db4087d5e6e1c1aafa38788e749e5d7a24f5cb230f737954402886000013584600186516126cb9190613954565b815181106126db576126db613889565b60200260200101516040516126fa929190918252602082015260400190565b60405180910390a380600182516127119190613954565b8151811061272157612721613889565b6020026020010151915050949350505050565b6040516001600160a01b038316602482015260448101829052610ad69084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152612e91565b80158061285857506040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612832573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285691906138eb565b155b6128ca5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161095d565b6040516001600160a01b038316602482015260448101829052610ad69084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401612779565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561298e57600080fd5b505af11580156129a2573d6000803e3d6000fd5b5050505050565b306001600160a01b03821614610ad6576001600160a01b0383166129fd576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610e5c573d6000803e3d6000fd5b610ad66001600160a01b0384168284612734565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015612a6c57600080fd5b505af1158015612a80573d6000803e3d6000fd5b505050505050565b60408051602080825281830190925260609160208201818036833750505060208101929092525090565b612add6040518060800160405280606081526020016060815260200160608152602001600081525090565b604051806080016040528083600001518152602001836020015181526020018360400151815260200183606001518152509050919050565b8460400151612b2c836001600160a01b0316612a88565b604051602001612b3d9291906139b3565b60408051601f198184030181529181528601526020850151612b676001600160a01b038516612a88565b604051602001612b789291906139b3565b60408051601f1981840301815291905260208601528451612b9885612a88565b604051602001612ba99291906139b3565b60408051601f198184030181529190528552606085018051829190612bcf9083906139a0565b9052505050505050565b604081015180516000916108d491612c87565b60408101515181516000916108d49190612c87565b606060208251612c11919061397e565b67ffffffffffffffff811115612c2957612c296134fc565b604051908082528060200260200182016040528015612c52578160200160208202803683370190505b50905060005b60208351612c66919061397e565b811015612cb157612c8c83612c7c836020613967565b612c879060206139a0565b015190565b828281518110612c9e57612c9e613889565b6020908102919091010152600101612c58565b50919050565b606060208251612cc7919061397e565b67ffffffffffffffff811115612cdf57612cdf6134fc565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b60208351612d1c919061397e565b811015612cb157612d3283612c7c836020613967565b828281518110612d4457612d44613889565b6001600160a01b0390921660209283029190910190910152600101612d0e565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610c3457612d9581612fcd565b612da0836020612fdf565b604051602001612db19291906139e2565b60408051601f198184030181529082905262461bcd60e51b825261095d916004016137c9565b6000600154821015612e2b5760405162461bcd60e51b815260206004820152601b60248201527f59616b526f757465723a20496e73756666696369656e74206665650000000000604482015260640161095d565b612710612e388382613954565b612e429085613967565b612e4c919061397e565b9392505050565b6001600160a01b0383163014612e7d57612e786001600160a01b0385168484846131c0565b610e5c565b610e5c6001600160a01b0385168383612734565b600080836001600160a01b031683604051612eac9190613a63565b6000604051808303816000865af19150503d8060008114612ee9576040519150601f19603f3d011682016040523d82523d6000602084013e612eee565b606091505b509150915081612f405760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640161095d565b805115610e5c5780806020019051810190612f5b9190613a7f565b610e5c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161095d565b60606108d46001600160a01b03831660145b60606000612fee836002613967565b612ff99060026139a0565b67ffffffffffffffff811115613011576130116134fc565b6040519080825280601f01601f19166020018201604052801561303b576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061307257613072613889565b60200101906001600160f81b031916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106130bd576130bd613889565b60200101906001600160f81b031916908160001a90535060006130e1846002613967565b6130ec9060016139a0565b90505b6001811115613171577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061312d5761312d613889565b1a60f81b82828151811061314357613143613889565b60200101906001600160f81b031916908160001a90535060049490941c9361316a81613aa1565b90506130ef565b508315612e4c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161095d565b6040516001600160a01b0380851660248301528316604482015260648101829052610e5c9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612779565b828054828255906000526020600020908101928215613273579160200282015b82811115613273578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613231565b5061327f929150613283565b5090565b5b8082111561327f5760008155600101613284565b6000602082840312156132aa57600080fd5b81356001600160e01b031981168114612e4c57600080fd5b80356001600160a01b03811681146132d957600080fd5b919050565b600080600080600060a086880312156132f657600080fd5b85359450613306602087016132c2565b9350613314604087016132c2565b94979396509394606081013594506080013592915050565b600081518084526020840193506020830160005b828110156133675781516001600160a01b0316865260209586019590910190600101613340565b5093949350505050565b60208082528251608083830152805160a084018190526000929190910190829060c08501905b808310156133ba5783518252602082019150602084019350600183019250613397565b506020860151858203601f1901604087015292506133d8818461332c565b925050506040840151601f198483030160608501526133f7828261332c565b915050606084015160808401528091505092915050565b600060808284031215612cb157600080fd5b803560ff811681146132d957600080fd5b600080600080600080600060e0888a03121561344c57600080fd5b873567ffffffffffffffff81111561346357600080fd5b61346f8a828b0161340e565b97505061347e602089016132c2565b9550604088013594506060880135935061349a60808901613420565b9699959850939692959460a0840135945060c09093013592915050565b6000602082840312156134c957600080fd5b5035919050565b600080604083850312156134e357600080fd5b823591506134f3602084016132c2565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561352457600080fd5b813567ffffffffffffffff81111561353b57600080fd5b8201601f8101841361354c57600080fd5b803567ffffffffffffffff811115613566576135666134fc565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715613593576135936134fc565b6040529182526020818401810192908101878411156135b157600080fd5b6020850194505b838510156112a5576135c9856132c2565b8152602094850194016135b8565b600080600080608085870312156135ed57600080fd5b843593506135fd602086016132c2565b925061360b604086016132c2565b9396929550929360600135925050565b60006020828403121561362d57600080fd5b612e4c826132c2565b60008060006060848603121561364b57600080fd5b833567ffffffffffffffff81111561366257600080fd5b61366e8682870161340e565b93505061367d602085016132c2565b929592945050506040919091013590565b600080600080608085870312156136a457600080fd5b843593506136b4602086016132c2565b92506136c2604086016132c2565b91506136d060608601613420565b905092959194509250565b600080604083850312156136ee57600080fd5b6136f7836132c2565b946020939093013593505050565b60008060008060006080868803121561371d57600080fd5b8535945061372d602087016132c2565b935061373b604087016132c2565b9250606086013567ffffffffffffffff81111561375757600080fd5b8601601f8101881361376857600080fd5b803567ffffffffffffffff81111561377f57600080fd5b8860208260051b840101111561379457600080fd5b959894975092955050506020019190565b60005b838110156137c05781810151838201526020016137a8565b50506000910152565b60208152600082518060208401526137e88160408501602087016137a5565b601f01601f19169190910160400192915050565b60008060006060848603121561381157600080fd5b83359250613821602085016132c2565b915061382f604085016132c2565b90509250925092565b6000808335601e1984360301811261384f57600080fd5b83018035915067ffffffffffffffff82111561386a57600080fd5b6020019150600581901b360382131561388257600080fd5b9250929050565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000918401906040840190835b818110156138e05783516001600160a01b03168352602093840193909201916001016138b9565b509095945050505050565b6000602082840312156138fd57600080fd5b5051919050565b60006020828403121561391657600080fd5b612e4c82613420565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff810361394b5761394b61391f565b60010192915050565b818103818111156108d4576108d461391f565b80820281158282048414176108d4576108d461391f565b60008261399b57634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156108d4576108d461391f565b600083516139c58184602088016137a5565b8351908301906139d98183602088016137a5565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613a1a8160178501602088016137a5565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613a578160288401602088016137a5565b01602801949350505050565b60008251613a758184602087016137a5565b9190910192915050565b600060208284031215613a9157600080fd5b81518015158114612e4c57600080fd5b600081613ab057613ab061391f565b50600019019056fea2646970667358221220575615ac6436fffd937b5b7a3a2a5f11dcace2efe2d86da70552311ae1eacc7c64736f6c634300081b0033a54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d394d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000c683c8ae60d4f1962f2c8a234d2c3b85cbc26be6000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000000000000000000000000000000000000000000040000000000000000000000009d32645062c7fb3113ff4904317b61ebe3c0d20800000000000000000000000087ab393c066f21eeea1823ceaab7c4b1ad1c8b87000000000000000000000000247890a4582bc3182797942747e41a0ed3ae6e590000000000000000000000008a5eda0ee373dc0803cd1cdf7b2fdf119950697e0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000029219dd400f2bf60e5a23d13be72b486d40388940000000000000000000000000e0ce4d450c705f8a0b6dd9d5123e3df2787d16b0000000000000000000000002d0e0814e62d80056181f5cd932274405966e4f000000000000000000000000050c42deacd8fc9773493ed674b675be577f2634b
Deployed Bytecode
0x6080604052600436106102a35760003560e01c80638bb9c5bf1161016e578063c8a3a5c6116100cb578063dede7f151161007f578063f2fde38b11610064578063f2fde38b1461080a578063f87422541461082a578063fe38c5e61461085e57600080fd5b8063dede7f15146107ca578063f0350382146107ea57600080fd5b8063d73792a9116100b0578063d73792a914610774578063d8baf7cf1461078a578063dd8544b3146107aa57600080fd5b8063c8a3a5c614610734578063d547741f1461075457600080fd5b8063a217fddf11610122578063aede369311610107578063aede3693146106c0578063b381cf40146106e0578063c3accd481461071457600080fd5b8063a217fddf14610655578063a3f4df7e1461066a57600080fd5b806392f5d88a1161015357806392f5d88a146105ad578063952e901214610620578063a0cf0aea1461064057600080fd5b80638bb9c5bf1461054957806391d148541461056957600080fd5b80634c09cf4e1161021c57806376c7a3c7116101d05780637c7a561b116101b55780637c7a561b146104f4578063809356aa146105095780638980f11f1461052957600080fd5b806376c7a3c7146104c957806376ebe69c146104df57600080fd5b80636b453c1f116102015780636b453c1f146104695780636bf2df861461048957806375d19947146104a957600080fd5b80634c09cf4e1461042957806352a52ab01461044957600080fd5b8063248a9ca31161027357806331ac99201161025857806331ac9920146103c957806336568abe146103e95780633a9a40811461040957600080fd5b8063248a9ca31461036b5780632f2ff15d146103a957600080fd5b8062b99e36146102af57806301ffc9a7146102ec578063061b15e71461031c5780631e189dc21461034957600080fd5b366102aa57005b600080fd5b3480156102bb57600080fd5b506002546102cf906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102f857600080fd5b5061030c610307366004613298565b610871565b60405190151581526020016102e3565b34801561032857600080fd5b5061033c6103373660046132de565b6108da565b6040516102e39190613371565b34801561035557600080fd5b50610369610364366004613431565b6109e4565b005b34801561037757600080fd5b5061039b6103863660046134b7565b60009081526020819052604090206001015490565b6040519081526020016102e3565b3480156103b557600080fd5b506103696103c43660046134d0565b610ab1565b3480156103d557600080fd5b506103696103e43660046134b7565b610adb565b3480156103f557600080fd5b506103696104043660046134d0565b610bac565b34801561041557600080fd5b50610369610424366004613512565b610c38565b34801561043557600080fd5b5061033c6104443660046135d7565b610d11565b34801561045557600080fd5b506102cf6104643660046134b7565b610df9565b34801561047557600080fd5b5061036961048436600461361b565b610e23565b34801561049557600080fd5b506103696104a4366004613636565b610e50565b3480156104b557600080fd5b506103696104c4366004613431565b610e62565b3480156104d557600080fd5b5061039b60015481565b3480156104eb57600080fd5b5060035461039b565b34801561050057600080fd5b5060045461039b565b34801561051557600080fd5b5061039b61052436600461368e565b610f26565b34801561053557600080fd5b506103696105443660046136db565b610fd2565b34801561055557600080fd5b506103696105643660046134b7565b61110d565b34801561057557600080fd5b5061030c6105843660046134d0565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b3480156105b957600080fd5b506105cd6105c8366004613705565b611118565b6040516102e3919060006080820190506001600160a01b0383511682526001600160a01b0360208401511660208301526001600160a01b0360408401511660408301526060830151606083015292915050565b34801561062c57600080fd5b506102cf61063b3660046134b7565b6112b0565b34801561064c57600080fd5b506102cf600081565b34801561066157600080fd5b5061039b600081565b34801561067657600080fd5b506106b36040518060400160405280600981526020017f59616b526f75746572000000000000000000000000000000000000000000000081525081565b6040516102e391906137c9565b3480156106cc57600080fd5b506103696106db3660046134b7565b6112c0565b3480156106ec57600080fd5b506102cf7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3881565b34801561072057600080fd5b5061036961072f36600461361b565b611407565b34801561074057600080fd5b5061036961074f366004613512565b61150d565b34801561076057600080fd5b5061036961076f3660046134d0565b6115e6565b34801561078057600080fd5b5061039b61271081565b34801561079657600080fd5b506103696107a536600461361b565b61160b565b3480156107b657600080fd5b506103696107c536600461361b565b611635565b3480156107d657600080fd5b506105cd6107e53660046137fc565b6116da565b3480156107f657600080fd5b50610369610805366004613636565b611849565b34801561081657600080fd5b5061036961082536600461361b565b61195f565b34801561083657600080fd5b5061039b7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab9581565b61036961086c366004613636565b611976565b60006001600160e01b031982167f7965db0b0000000000000000000000000000000000000000000000000000000014806108d457507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b6109056040518060800160405280606081526020016060815260200160608152602001600081525090565b6000831180156109155750600583105b6109665760405162461bcd60e51b815260206004820152601c60248201527f59616b526f757465723a20496e76616c6964206d61782d73746570730000000060448201526064015b60405180910390fd5b60006109728787611a65565b9050600080841161098457600061098e565b61098e8487611ab8565b905061099e888888888686611b4d565b91508160200151516000036109cf576040805160208082018352600080835291855282519081018352908152908301525b6109d882611e87565b98975050505050505050565b6109f16040880188613838565b6000818110610a0257610a02613889565b9050602002016020810190610a17919061361b565b60405163d505accf60e01b8152336004820152306024820152883560448201526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b03919091169063d505accf9060e401600060405180830381600087803b158015610a8557600080fd5b505af1158015610a99573d6000803e3d6000fd5b50505050610aa8878787611849565b50505050505050565b600082815260208190526040902060010154610acc81611f02565b610ad68383611f0c565b505050565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff16610b6a5760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b60015460408051918252602082018490527f4bb8a6184424e4bb853a4836042f5a726e4e710873989bfc6abdab19966f5b70910160405180910390a150600155565b6001600160a01b0381163314610c2a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c660000000000000000000000000000000000606482015260840161095d565b610c348282611faa565b5050565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff16610cc75760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b7febf7325f48e05e5e38809c69f8b02a7c907ed31d8768e6c2d841b1296a9225fe82604051610cf6919061389f565b60405180910390a18151610ad6906004906020850190613211565b610d3c6040518060800160405280606081526020016060815260200160608152602001600081525090565b600082118015610d4c5750600582105b610d985760405162461bcd60e51b815260206004820152601c60248201527f59616b526f757465723a20496e76616c6964206d61782d737465707300000000604482015260640161095d565b6000610da48686611a65565b9050610db586868686856000611b4d565b9050806020015151600003610de6576040805160208082018352600080835291845282519081018352908152908201525b610def81611e87565b9695505050505050565b60038181548110610e0957600080fd5b6000918252602090912001546001600160a01b0316905081565b610e4d7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab9582610ab1565b50565b610e5c83338484612029565b50505050565b610e6f6040880188613838565b6000818110610e8057610e80613889565b9050602002016020810190610e95919061361b565b60405163d505accf60e01b8152336004820152306024820152883560448201526064810186905260ff8516608482015260a4810184905260c481018390526001600160a01b03919091169063d505accf9060e401600060405180830381600087803b158015610f0357600080fd5b505af1158015610f17573d6000803e3d6000fd5b50505050610aa8878787610e50565b60008060048360ff1681548110610f3f57610f3f613889565b60009182526020822001546040516377ccc49d60e11b8152600481018990526001600160a01b03888116602483015287811660448301529091169250829063ef99893a90606401602060405180830381865afa158015610fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc791906138eb565b979650505050505050565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff166110615760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b600082116110b15760405162461bcd60e51b815260206004820152601260248201527f4e6f7468696e6720746f207265636f7665720000000000000000000000000000604482015260640161095d565b6110c56001600160a01b0384163384612734565b826001600160a01b03167f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa288360405161110091815260200190565b60405180910390a2505050565b33610c348282610bac565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260005b60ff81168411156112a5576000600486868460ff1681811061118757611187613889565b905060200201602081019061119c9190613904565b60ff16815481106111af576111af613889565b60009182526020822001546040516377ccc49d60e11b8152600481018c90526001600160a01b038b811660248301528a811660448301529091169250829063ef99893a90606401602060405180830381865afa158015611213573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123791906138eb565b905060ff8316158061124c5750836060015181115b15611290576040518060800160405280836001600160a01b031681526020018a6001600160a01b03168152602001896001600160a01b031681526020018281525093505b5050808061129d90613935565b915050611163565b509695505050505050565b60048181548110610e0957600080fd5b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff1661134f5760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b6000821161139f5760405162461bcd60e51b815260206004820152601260248201527f4e6f7468696e6720746f207265636f7665720000000000000000000000000000604482015260640161095d565b604051339083156108fc029084906000818181858888f193505050501580156113cc573d6000803e3d6000fd5b506040518281526000907f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa289060200160405180910390a25050565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff166114965760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b600254604080516001600160a01b03928316815291841660208301527fb2c853ac4d80d18d058c43d8018d077a036e542a79acae1647f5ad2a8c76f4e2910160405180910390a1506002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff1661159c5760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b7f658ff1688002926d8f426cb10c052ec29003f50042df9652d8613484c1a58647826040516115cb919061389f565b60405180910390a18151610ad6906003906020850190613211565b60008281526020819052604090206001015461160181611f02565b610ad68383611faa565b610e4d7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab95826115e6565b3360008181527fa54247010af6b3693b80aceddfad12e077c5de3571e6243fada502635f0d7d39602052604090205460ff166116c45760405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b606482015260840161095d565b610c346001600160a01b038316836000196127c5565b60408051608081018252600080825260208201819052918101829052606081019190915260408051608081018252600080825260208201819052918101829052606081019190915260005b60045460ff8216101561184057600060048260ff168154811061174a5761174a613889565b60009182526020822001546040516377ccc49d60e11b8152600481018a90526001600160a01b03898116602483015288811660448301529091169250829063ef99893a90606401602060405180830381865afa1580156117ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d291906138eb565b905060ff831615806117e75750836060015181115b1561182b576040518060800160405280836001600160a01b03168152602001886001600160a01b03168152602001876001600160a01b031681526020018281525093505b5050808061183890613935565b915050611725565b50949350505050565b6001600160a01b037f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38166118806040850185613838565b600161188f6040880188613838565b61189a929150613954565b8181106118a9576118a9613889565b90506020020160208101906118be919061361b565b6001600160a01b03161461193a5760405162461bcd60e51b815260206004820152602760248201527f59616b526f757465723a2050617468206e6565647320746f20656e642077697460448201527f6820574156415800000000000000000000000000000000000000000000000000606482015260840161095d565b600061194884333085612029565b905061195381612913565b610e5c600082856129a9565b3361196b600083610ab1565b610c34600082610bac565b6001600160a01b037f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38166119ad6040850185613838565b60008181106119be576119be613889565b90506020020160208101906119d3919061361b565b6001600160a01b031614611a4f5760405162461bcd60e51b815260206004820152602960248201527f59616b526f757465723a2050617468206e6565647320746f20626567696e207760448201527f6974682057415641580000000000000000000000000000000000000000000000606482015260840161095d565b611a598335612a11565b610e5c83308484612029565b611a906040518060800160405280606081526020016060815260200160608152602001600081525090565b611a9983612a88565b8152611aad6001600160a01b038316612a88565b604082015292915050565b600080611af0670de0b6b3a76400007f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38856002610d11565b9050806040015151600014611b465780518051633b9aca00918691611b1790600190613954565b81518110611b2757611b27613889565b6020026020010151611b399190613967565b611b43919061397e565b91505b5092915050565b611b786040518060800160405280606081526020016060815260200160608152602001600081525090565b6000611b8384612ab2565b905060008084151581611b978c8c8c6116da565b90508060600151600014611c36578115611c145780600001516001600160a01b03166369cff80d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bed573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1191906138eb565b92505b606081015181516040830151611c2e928892909187612b15565b806060015193505b600189118015611c615750611c4c60028a613954565b6020896020015151611c5e919061397e565b11155b15611e775760005b600354811015611e755760038181548110611c8657611c86613889565b6000918252602090912001546001600160a01b038d8116911614611e6d576000611cd88e8e60038581548110611cbe57611cbe613889565b6000918252602090912001546001600160a01b03166116da565b90508060600151600003611cec5750611e6d565b6000611cf78b612ab2565b90508415611d685781600001516001600160a01b03166369cff80d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611d41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d6591906138eb565b95505b606082015182516040840151611d8292849290918a612b15565b611dbb826060015160038581548110611d9d57611d9d613889565b6000918252602090912001546001600160a01b03168f8f858f611b4d565b90506000611dc882612bd9565b90506000611dd583612bec565b9050816001600160a01b03168f6001600160a01b0316148015611df757508881115b15611e6857896060015183606001511115611e61576000633b9aca008b606001518560600151611e279190613954565b611e31908f613967565b611e3b919061397e565b90506000611e498b84613954565b905080821115611e5e57505050505050611e6d565b50505b8098508299505b505050505b600101611c69565b505b50929a9950505050505050505050565b611eb26040518060800160405280606081526020016060815260200160608152602001600081525090565b6040518060800160405280611eca8460000151612c01565b8152602001611edc8460200151612cb7565b8152602001611eee8460400151612cb7565b815260200183606001518152509050919050565b610e4d8133612d64565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610c34576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055611f663390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615610c34576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000806120396040870187613838565b905067ffffffffffffffff811115612053576120536134fc565b60405190808252806020026020018201604052801561207c578160200160208202803683370190505b509050600083118061209057506000600154115b15612137576120a0863584612dd7565b816000815181106120b3576120b3613889565b60209081029190910101526121326120ce6040880188613838565b60008181106120df576120df613889565b90506020020160208101906120f4919061361b565b600254835188916001600160a01b031690859060009061211657612116613889565b60200260200101518a6000013561212d9190613954565b612e53565b61215c565b85600001358160008151811061214f5761214f613889565b6020026020010181815250505b6121e661216c6040880188613838565b600081811061217d5761217d613889565b9050602002016020810190612192919061361b565b866121a060608a018a613838565b60008181106121b1576121b1613889565b90506020020160208101906121c6919061361b565b846000815181106121d9576121d9613889565b6020026020010151612e53565b60005b6121f66060880188613838565b905081101561236f5761220c6060880188613838565b8281811061221c5761221c613889565b9050602002016020810190612231919061361b565b6001600160a01b031663ef99893a83838151811061225157612251613889565b60200260200101518980604001906122699190613838565b8581811061227957612279613889565b905060200201602081019061228e919061361b565b61229b60408c018c613838565b6122a68760016139a0565b8181106122b5576122b5613889565b90506020020160208101906122ca919061361b565b6040516001600160e01b031960e086901b16815260048101939093526001600160a01b039182166024840152166044820152606401602060405180830381865afa15801561231c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234091906138eb565b8261234c8360016139a0565b8151811061235c5761235c613889565b60209081029190910101526001016121e9565b50856020013581600183516123849190613954565b8151811061239457612394613889565b602002602001015110156124105760405162461bcd60e51b815260206004820152602560248201527f59616b526f757465723a20496e73756666696369656e74206f7574707574206160448201527f6d6f756e74000000000000000000000000000000000000000000000000000000606482015260840161095d565b60005b6124206060880188613838565b9050811015612605576000600161243a60608a018a613838565b612445929150613954565b8210612451578561248d565b61245e6060890189613838565b6124698460016139a0565b81811061247857612478613889565b905060200201602081019061248d919061361b565b905061249c6060890189613838565b838181106124ac576124ac613889565b90506020020160208101906124c1919061361b565b6001600160a01b031663eab90da68484815181106124e1576124e1613889565b6020026020010151858560016124f791906139a0565b8151811061250757612507613889565b60200260200101518b806040019061251f9190613838565b8781811061252f5761252f613889565b9050602002016020810190612544919061361b565b61255160408e018e613838565b61255c8960016139a0565b81811061256b5761256b613889565b9050602002016020810190612580919061361b565b6040516001600160e01b031960e087901b168152600481019490945260248401929092526001600160a01b03908116604484015290811660648301528416608482015260a401600060405180830381600087803b1580156125e057600080fd5b505af11580156125f4573d6000803e3d6000fd5b505060019093019250612413915050565b506126136040870187613838565b600161262260408a018a613838565b61262d929150613954565b81811061263c5761263c613889565b9050602002016020810190612651919061361b565b6001600160a01b03166126676040880188613838565b600081811061267857612678613889565b905060200201602081019061268d919061361b565b6001600160a01b03167f9fc8352e52998db4087d5e6e1c1aafa38788e749e5d7a24f5cb230f737954402886000013584600186516126cb9190613954565b815181106126db576126db613889565b60200260200101516040516126fa929190918252602082015260400190565b60405180910390a380600182516127119190613954565b8151811061272157612721613889565b6020026020010151915050949350505050565b6040516001600160a01b038316602482015260448101829052610ad69084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152612e91565b80158061285857506040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015612832573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285691906138eb565b155b6128ca5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e636500000000000000000000606482015260840161095d565b6040516001600160a01b038316602482015260448101829052610ad69084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401612779565b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad386001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561298e57600080fd5b505af11580156129a2573d6000803e3d6000fd5b5050505050565b306001600160a01b03821614610ad6576001600160a01b0383166129fd576040516001600160a01b0382169083156108fc029084906000818181858888f19350505050158015610e5c573d6000803e3d6000fd5b610ad66001600160a01b0384168284612734565b7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad386001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015612a6c57600080fd5b505af1158015612a80573d6000803e3d6000fd5b505050505050565b60408051602080825281830190925260609160208201818036833750505060208101929092525090565b612add6040518060800160405280606081526020016060815260200160608152602001600081525090565b604051806080016040528083600001518152602001836020015181526020018360400151815260200183606001518152509050919050565b8460400151612b2c836001600160a01b0316612a88565b604051602001612b3d9291906139b3565b60408051601f198184030181529181528601526020850151612b676001600160a01b038516612a88565b604051602001612b789291906139b3565b60408051601f1981840301815291905260208601528451612b9885612a88565b604051602001612ba99291906139b3565b60408051601f198184030181529190528552606085018051829190612bcf9083906139a0565b9052505050505050565b604081015180516000916108d491612c87565b60408101515181516000916108d49190612c87565b606060208251612c11919061397e565b67ffffffffffffffff811115612c2957612c296134fc565b604051908082528060200260200182016040528015612c52578160200160208202803683370190505b50905060005b60208351612c66919061397e565b811015612cb157612c8c83612c7c836020613967565b612c879060206139a0565b015190565b828281518110612c9e57612c9e613889565b6020908102919091010152600101612c58565b50919050565b606060208251612cc7919061397e565b67ffffffffffffffff811115612cdf57612cdf6134fc565b604051908082528060200260200182016040528015612d08578160200160208202803683370190505b50905060005b60208351612d1c919061397e565b811015612cb157612d3283612c7c836020613967565b828281518110612d4457612d44613889565b6001600160a01b0390921660209283029190910190910152600101612d0e565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16610c3457612d9581612fcd565b612da0836020612fdf565b604051602001612db19291906139e2565b60408051601f198184030181529082905262461bcd60e51b825261095d916004016137c9565b6000600154821015612e2b5760405162461bcd60e51b815260206004820152601b60248201527f59616b526f757465723a20496e73756666696369656e74206665650000000000604482015260640161095d565b612710612e388382613954565b612e429085613967565b612e4c919061397e565b9392505050565b6001600160a01b0383163014612e7d57612e786001600160a01b0385168484846131c0565b610e5c565b610e5c6001600160a01b0385168383612734565b600080836001600160a01b031683604051612eac9190613a63565b6000604051808303816000865af19150503d8060008114612ee9576040519150601f19603f3d011682016040523d82523d6000602084013e612eee565b606091505b509150915081612f405760405162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015260640161095d565b805115610e5c5780806020019051810190612f5b9190613a7f565b610e5c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161095d565b60606108d46001600160a01b03831660145b60606000612fee836002613967565b612ff99060026139a0565b67ffffffffffffffff811115613011576130116134fc565b6040519080825280601f01601f19166020018201604052801561303b576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061307257613072613889565b60200101906001600160f81b031916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106130bd576130bd613889565b60200101906001600160f81b031916908160001a90535060006130e1846002613967565b6130ec9060016139a0565b90505b6001811115613171577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061312d5761312d613889565b1a60f81b82828151811061314357613143613889565b60200101906001600160f81b031916908160001a90535060049490941c9361316a81613aa1565b90506130ef565b508315612e4c5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161095d565b6040516001600160a01b0380851660248301528316604482015260648101829052610e5c9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401612779565b828054828255906000526020600020908101928215613273579160200282015b82811115613273578251825473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03909116178255602090920191600190910190613231565b5061327f929150613283565b5090565b5b8082111561327f5760008155600101613284565b6000602082840312156132aa57600080fd5b81356001600160e01b031981168114612e4c57600080fd5b80356001600160a01b03811681146132d957600080fd5b919050565b600080600080600060a086880312156132f657600080fd5b85359450613306602087016132c2565b9350613314604087016132c2565b94979396509394606081013594506080013592915050565b600081518084526020840193506020830160005b828110156133675781516001600160a01b0316865260209586019590910190600101613340565b5093949350505050565b60208082528251608083830152805160a084018190526000929190910190829060c08501905b808310156133ba5783518252602082019150602084019350600183019250613397565b506020860151858203601f1901604087015292506133d8818461332c565b925050506040840151601f198483030160608501526133f7828261332c565b915050606084015160808401528091505092915050565b600060808284031215612cb157600080fd5b803560ff811681146132d957600080fd5b600080600080600080600060e0888a03121561344c57600080fd5b873567ffffffffffffffff81111561346357600080fd5b61346f8a828b0161340e565b97505061347e602089016132c2565b9550604088013594506060880135935061349a60808901613420565b9699959850939692959460a0840135945060c09093013592915050565b6000602082840312156134c957600080fd5b5035919050565b600080604083850312156134e357600080fd5b823591506134f3602084016132c2565b90509250929050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561352457600080fd5b813567ffffffffffffffff81111561353b57600080fd5b8201601f8101841361354c57600080fd5b803567ffffffffffffffff811115613566576135666134fc565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715613593576135936134fc565b6040529182526020818401810192908101878411156135b157600080fd5b6020850194505b838510156112a5576135c9856132c2565b8152602094850194016135b8565b600080600080608085870312156135ed57600080fd5b843593506135fd602086016132c2565b925061360b604086016132c2565b9396929550929360600135925050565b60006020828403121561362d57600080fd5b612e4c826132c2565b60008060006060848603121561364b57600080fd5b833567ffffffffffffffff81111561366257600080fd5b61366e8682870161340e565b93505061367d602085016132c2565b929592945050506040919091013590565b600080600080608085870312156136a457600080fd5b843593506136b4602086016132c2565b92506136c2604086016132c2565b91506136d060608601613420565b905092959194509250565b600080604083850312156136ee57600080fd5b6136f7836132c2565b946020939093013593505050565b60008060008060006080868803121561371d57600080fd5b8535945061372d602087016132c2565b935061373b604087016132c2565b9250606086013567ffffffffffffffff81111561375757600080fd5b8601601f8101881361376857600080fd5b803567ffffffffffffffff81111561377f57600080fd5b8860208260051b840101111561379457600080fd5b959894975092955050506020019190565b60005b838110156137c05781810151838201526020016137a8565b50506000910152565b60208152600082518060208401526137e88160408501602087016137a5565b601f01601f19169190910160400192915050565b60008060006060848603121561381157600080fd5b83359250613821602085016132c2565b915061382f604085016132c2565b90509250925092565b6000808335601e1984360301811261384f57600080fd5b83018035915067ffffffffffffffff82111561386a57600080fd5b6020019150600581901b360382131561388257600080fd5b9250929050565b634e487b7160e01b600052603260045260246000fd5b602080825282518282018190526000918401906040840190835b818110156138e05783516001600160a01b03168352602093840193909201916001016138b9565b509095945050505050565b6000602082840312156138fd57600080fd5b5051919050565b60006020828403121561391657600080fd5b612e4c82613420565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff810361394b5761394b61391f565b60010192915050565b818103818111156108d4576108d461391f565b80820281158282048414176108d4576108d461391f565b60008261399b57634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156108d4576108d461391f565b600083516139c58184602088016137a5565b8351908301906139d98183602088016137a5565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613a1a8160178501602088016137a5565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613a578160288401602088016137a5565b01602801949350505050565b60008251613a758184602087016137a5565b9190910192915050565b600060208284031215613a9157600080fd5b81518015158114612e4c57600080fd5b600081613ab057613ab061391f565b50600019019056fea2646970667358221220575615ac6436fffd937b5b7a3a2a5f11dcace2efe2d86da70552311ae1eacc7c64736f6c634300081b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000120000000000000000000000000c683c8ae60d4f1962f2c8a234d2c3b85cbc26be6000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000000000000000000000000000000000000000000040000000000000000000000009d32645062c7fb3113ff4904317b61ebe3c0d20800000000000000000000000087ab393c066f21eeea1823ceaab7c4b1ad1c8b87000000000000000000000000247890a4582bc3182797942747e41a0ed3ae6e590000000000000000000000008a5eda0ee373dc0803cd1cdf7b2fdf119950697e0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000029219dd400f2bf60e5a23d13be72b486d40388940000000000000000000000000e0ce4d450c705f8a0b6dd9d5123e3df2787d16b0000000000000000000000002d0e0814e62d80056181f5cd932274405966e4f000000000000000000000000050c42deacd8fc9773493ed674b675be577f2634b
-----Decoded View---------------
Arg [0] : _adapters (address[]): 0x9d32645062c7Fb3113fF4904317b61eBE3c0d208,0x87Ab393c066F21eeeA1823CEAAB7c4b1ad1c8b87,0x247890a4582Bc3182797942747E41a0ED3Ae6E59,0x8a5eDa0eE373dc0803Cd1cDf7b2FDf119950697e
Arg [1] : _trustedTokens (address[]): 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38,0x29219dd400f2Bf60E5a23d13Be72B486D4038894,0x0e0Ce4D450c705F8a0B6Dd9d5123e3df2787D16B,0x2D0E0814E62D80056181F5cd932274405966e4f0,0x50c42dEAcD8Fc9773493ED674b675bE577f2634b
Arg [2] : _feeClaimer (address): 0xC683C8aE60d4f1962F2c8a234d2c3b85cBc26be6
Arg [3] : _wrapped_native (address): 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38
-----Encoded View---------------
15 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 000000000000000000000000c683c8ae60d4f1962f2c8a234d2c3b85cbc26be6
Arg [3] : 000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [5] : 0000000000000000000000009d32645062c7fb3113ff4904317b61ebe3c0d208
Arg [6] : 00000000000000000000000087ab393c066f21eeea1823ceaab7c4b1ad1c8b87
Arg [7] : 000000000000000000000000247890a4582bc3182797942747e41a0ed3ae6e59
Arg [8] : 0000000000000000000000008a5eda0ee373dc0803cd1cdf7b2fdf119950697e
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [10] : 000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Arg [11] : 00000000000000000000000029219dd400f2bf60e5a23d13be72b486d4038894
Arg [12] : 0000000000000000000000000e0ce4d450c705f8a0b6dd9d5123e3df2787d16b
Arg [13] : 0000000000000000000000002d0e0814e62d80056181f5cd932274405966e4f0
Arg [14] : 00000000000000000000000050c42deacd8fc9773493ed674b675be577f2634b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.