More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 197,636 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap No Split | 4879500 | 10 mins ago | IN | 0 APE | 0.01001793 | ||||
Swap No Split | 4879282 | 13 mins ago | IN | 0 APE | 0.01003916 | ||||
Swap No Split | 4879035 | 17 mins ago | IN | 0 APE | 0.01009359 | ||||
Swap No Split | 4879025 | 17 mins ago | IN | 0 APE | 0.01055886 | ||||
Swap No Split | 4878835 | 20 mins ago | IN | 0 APE | 0.00947108 | ||||
Swap No Split | 4878825 | 20 mins ago | IN | 0 APE | 0.00992258 | ||||
Swap No Split | 4878818 | 20 mins ago | IN | 0 APE | 0.00939345 | ||||
Swap No Split To... | 4878659 | 23 mins ago | IN | 0 APE | 0.01225391 | ||||
Swap No Split To... | 4878634 | 23 mins ago | IN | 0 APE | 0.01127138 | ||||
Swap No Split To... | 4878630 | 23 mins ago | IN | 0 APE | 0.01031927 | ||||
Swap No Split To... | 4878621 | 24 mins ago | IN | 0 APE | 0.01047177 | ||||
Swap No Split To... | 4878608 | 24 mins ago | IN | 0 APE | 0.01051097 | ||||
Swap No Split To... | 4878598 | 24 mins ago | IN | 0 APE | 0.0105312 | ||||
Swap No Split To... | 4878589 | 24 mins ago | IN | 0 APE | 0.01059193 | ||||
Swap No Split To... | 4878579 | 24 mins ago | IN | 0 APE | 0.0102846 | ||||
Swap No Split To... | 4878566 | 24 mins ago | IN | 0 APE | 0.01039584 | ||||
Swap No Split To... | 4878555 | 25 mins ago | IN | 0 APE | 0.01046104 | ||||
Swap No Split To... | 4878541 | 25 mins ago | IN | 0 APE | 0.0105419 | ||||
Swap No Split To... | 4878526 | 25 mins ago | IN | 0 APE | 0.01018721 | ||||
Swap No Split To... | 4878518 | 25 mins ago | IN | 0 APE | 0.01054282 | ||||
Swap No Split To... | 4878507 | 25 mins ago | IN | 0 APE | 0.01048036 | ||||
Swap No Split To... | 4878496 | 25 mins ago | IN | 0 APE | 0.01058204 | ||||
Swap No Split To... | 4878486 | 25 mins ago | IN | 0 APE | 0.01055144 | ||||
Swap No Split To... | 4878473 | 26 mins ago | IN | 0 APE | 0.01024786 | ||||
Swap No Split To... | 4878460 | 26 mins ago | IN | 0 APE | 0.01017935 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
4878659 | 23 mins ago | 86,786.26948606 APE | ||||
4878659 | 23 mins ago | 86,786.26948606 APE | ||||
4878634 | 23 mins ago | 87,226.38150323 APE | ||||
4878634 | 23 mins ago | 87,226.38150323 APE | ||||
4878630 | 23 mins ago | 437.00000259 APE | ||||
4878630 | 23 mins ago | 437.00000259 APE | ||||
4878621 | 24 mins ago | 437.00000273 APE | ||||
4878621 | 24 mins ago | 437.00000273 APE | ||||
4878608 | 24 mins ago | 437.00000286 APE | ||||
4878608 | 24 mins ago | 437.00000286 APE | ||||
4878598 | 24 mins ago | 437.00000299 APE | ||||
4878598 | 24 mins ago | 437.00000299 APE | ||||
4878589 | 24 mins ago | 437.00000312 APE | ||||
4878589 | 24 mins ago | 437.00000312 APE | ||||
4878579 | 24 mins ago | 437.00000352 APE | ||||
4878579 | 24 mins ago | 437.00000352 APE | ||||
4878566 | 24 mins ago | 437.00000365 APE | ||||
4878566 | 24 mins ago | 437.00000365 APE | ||||
4878555 | 25 mins ago | 437.00000378 APE | ||||
4878555 | 25 mins ago | 437.00000378 APE | ||||
4878541 | 25 mins ago | 437.00000418 APE | ||||
4878541 | 25 mins ago | 437.00000418 APE | ||||
4878526 | 25 mins ago | 437.00000483 APE | ||||
4878526 | 25 mins ago | 437.00000483 APE | ||||
4878518 | 25 mins ago | 437.00000496 APE |
Loading...
Loading
Contract Name:
CamelotYakRouter
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// ╟╗ ╔╬ // ╞╬╬ ╬╠╬ // ╔╣╬╬╬ ╠╠╠╠╦ // ╬╬╬╬╬╩ ╘╠╠╠╠╬ // ║╬╬╬╬╬ ╘╠╠╠╠╬ // ╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╒╬╬╬╬╬╬╬╜ ╠╠╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╬╬╬╬╬╬╬╬╠╠╠╠╠╠╠╠ // ╙╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╕ ╬╬╬╬╬╬╬╜ ╣╠╠╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╬╬╬╬╬╬╬╬╬╠╠╠╠╠╠╠╩ // ╙╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╔╬╬╬╬╬╬╬ ╔╠╠╠╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╣╬╬╬╬╬╬╬╬╬╬╬╠╠╠╠╝╙ // ╘╣╬╬╬╬╬╬╬╬╬╬╬╬╬╬ ╒╠╠╠╬╠╬╩╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╣╬╬╬╬╬╬╬╙ // ╣╬╬╬╬╬╬╬╬╬╬╠╣ ╣╬╠╠╠╬╩ ╚╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╬╬╬╬╬╬╬ // ╣╬╬╬╬╬╬╬╬╬╣ ╣╬╠╠╠╬╬ ╣╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╬╬╬╬╬╬╬ // ╟╬╬╬╬╬╬╬╩ ╬╬╠╠╠╠╬╬╬╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬╠╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╒╬╬╠╠╬╠╠╬╬╬╬╬╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╣╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╬╬╬╠╠╠╠╝╝╝╝╝╝╝╠╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╚╬╬╬╬╬╬╬╬ // ╬╬╬╬╬╬╬ ╣╬╬╬╬╠╠╩ ╘╬╬╬╬╬╬╬ ╠╬╬╬╬╬╬╬ ╙╬╬╬╬╬╬╬╬ // // SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.17; 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 CamelotYakRouter 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 = "CamelotYakRouter"; 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 ETH * @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, address) { IAdapter _adapter = IAdapter(ADAPTERS[_index]); try IAdapter(_adapter).query(_amountIn, _tokenIn, _tokenOut) returns (uint256 _amountOut, address _recipient) { return (_amountOut, _recipient); } catch { return (0, address(0)); } } /** * 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]]; try IAdapter(_adapter).query(_amountIn, _tokenIn, _tokenOut) returns (uint256 amountOut, address _recipient) { if (i == 0 || amountOut > bestQuery.amountOut) { bestQuery = Query(_adapter, _recipient, _tokenIn, _tokenOut, amountOut); } } catch { continue; } } 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]; try IAdapter(_adapter).query(_amountIn, _tokenIn, _tokenOut) returns (uint256 amountOut, address _recipient) { if (i == 0 || amountOut > bestQuery.amountOut) { bestQuery = Query(_adapter, _recipient, _tokenIn, _tokenOut, amountOut); } } catch { continue; } } return bestQuery; } /** * Return path with best returns between two tokens * Takes gas-cost into account */ function findBestPathWithGas( uint256 _amountIn, address _tokenIn, address _tokenOut, address[] memory _trustedTokens, 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; uint256 ttLength = TRUSTED_TOKENS.length; // Concatenate default and additional trusted tokens address[] memory _allTrustedTokens = new address[]( ttLength + _trustedTokens.length ); for (uint i = 0; i < ttLength; ) { _allTrustedTokens[i] = TRUSTED_TOKENS[i]; unchecked { i++; } } for (uint i = 0; i < _trustedTokens.length; ) { _allTrustedTokens[ttLength + i] = _trustedTokens[i]; unchecked { i++; } } queries = _findBestPath(_amountIn, _tokenIn, _tokenOut, _allTrustedTokens, _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) address[] memory _trustedTokens; FormattedOffer memory gasQuery = findBestPath(1e18, WNATIVE, _tokenOut, _trustedTokens, 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, address[] memory _trustedTokens, uint256 _maxSteps ) override public view returns (FormattedOffer memory) { require(_maxSteps > 0 && _maxSteps < 5, "YakRouter: Invalid max-steps"); Offer memory queries = OfferUtils.newOffer(_amountIn, _tokenIn); uint256 ttLength = TRUSTED_TOKENS.length; // Concatenate default and additional trusted tokens address[] memory _allTrustedTokens = new address[]( ttLength + _trustedTokens.length ); for (uint i = 0; i < ttLength; ) { _allTrustedTokens[i] = TRUSTED_TOKENS[i]; unchecked { i++; } } for (uint i = 0; i < _trustedTokens.length; ) { _allTrustedTokens[ttLength + i] = _trustedTokens[i]; unchecked { i++; } } queries = _findBestPath(_amountIn, _tokenIn, _tokenOut, _allTrustedTokens, _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, address[] memory _trustedTokens, 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.recipient, 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 < _trustedTokens.length; ) { if (_tokenIn == _trustedTokens[i]) { unchecked { 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, _trustedTokens[i]); if (bestSwap.amountOut == 0) { unchecked { i++; } 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.recipient, bestSwap.tokenOut, gasEstimate); newOffer = _findBestPath( bestSwap.amountOut, _trustedTokens[i], _tokenOut, _trustedTokens, _maxSteps, newOffer, _tknOutPriceNwei ); // Recursive step // Check that the last token in the path is the tokenOut and update the new best option if neccesary if ( _tokenOut == newOffer.getTokenOut() && newOffer.getAmountOut() > bestAmountOut ) { if (newOffer.gasEstimate > bestOption.gasEstimate) { uint256 gasCostDiff = (_tknOutPriceNwei * (newOffer.gasEstimate - bestOption.gasEstimate)) / 1e9; if ( gasCostDiff > newOffer.getAmountOut() - bestAmountOut ) { unchecked { i++; } continue; } } bestAmountOut = newOffer.getAmountOut(); bestOption = newOffer; } unchecked { i++; } } } return bestOption; } // -- SWAPPERS -- function _swapNoSplit( Trade calldata _trade, address _from, uint256 _fee, address _to ) internal returns (uint256) { uint256 amountIn = _trade.amountIn; if (_fee > 0 || MIN_FEE > 0) { // Transfer fees to the claimer account and decrease initial amount amountIn = _applyFee(_trade.amountIn, _fee); _transferFrom(_trade.path[0], _from, FEE_CLAIMER, _trade.amountIn - amountIn); } uint256 recipientBalanceBefore = IERC20(_trade.path[0]).balanceOf(_trade.recipients[0]); _transferFrom(_trade.path[0], _from, _trade.recipients[0], amountIn); amountIn = IERC20(_trade.path[0]).balanceOf(_trade.recipients[0]) - recipientBalanceBefore; address tokenOut = _trade.path[_trade.path.length - 1]; 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.recipients[i + 1] : _to; recipientBalanceBefore = IERC20(_trade.path[i + 1]).balanceOf(targetAddress); IAdapter(_trade.adapters[i]).swap( amountIn, 0, _trade.path[i], _trade.path[i + 1], targetAddress ); amountIn = IERC20(_trade.path[i + 1]).balanceOf(targetAddress) - recipientBalanceBefore; } uint256 amountOut = amountIn; require(amountOut >= _trade.amountOut, "YakRouter: Insufficient output amount"); emit YakSwap(_trade.path[0], tokenOut, _trade.amountIn, amountOut); return amountOut; } function swapNoSplit( Trade calldata _trade, uint256 _fee, address _to ) override public { _swapNoSplit(_trade, msg.sender, _fee, _to); } function swapNoSplitFromETH( Trade calldata _trade, uint256 _fee, address _to ) override external payable { require(_trade.path[0] == WNATIVE, "YakRouter: Path needs to begin with WETH"); _wrap(_trade.amountIn); _swapNoSplit(_trade, address(this), _fee, _to); } function swapNoSplitToETH( Trade calldata _trade, uint256 _fee, address _to ) override public { require(_trade.path[_trade.path.length - 1] == WNATIVE, "YakRouter: Path needs to end with WETH"); uint256 returnAmount = _swapNoSplit(_trade, msg.sender, _fee, address(this)); _unwrap(returnAmount); _returnTokensTo(NATIVE, returnAmount, _to); } /** * Swap token to token without the need to approve the first token */ function swapNoSplitWithPermit( Trade calldata _trade, uint256 _fee, address _to, 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, _fee, _to); } /** * Swap token to WETH without the need to approve the first token */ function swapNoSplitToETHWithPermit( Trade calldata _trade, uint256 _fee, address _to, 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); swapNoSplitToETH(_trade, _fee, _to); } }
// 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, address); }
// 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 recipient; address tokenIn; address tokenOut; uint256 amountOut; } struct Offer { bytes amounts; bytes adapters; bytes path; bytes recipients; uint256 gasEstimate; } struct FormattedOffer { uint256[] amounts; address[] adapters; address[] path; address[] recipients; uint256 gasEstimate; } struct Trade { uint256 amountIn; uint256 amountOut; address[] path; address[] adapters; address[] recipients; } 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, address); 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, address[] memory _trustedTokens, uint256 _maxSteps, uint256 _gasPrice ) external view returns (FormattedOffer memory); function findBestPath( uint256 _amountIn, address _tokenIn, address _tokenOut, address[] memory _trustedTokens, uint256 _maxSteps ) external view returns (FormattedOffer memory); // swap function swapNoSplit( Trade calldata _trade, uint256 _fee, address _to ) external; function swapNoSplitFromETH( Trade calldata _trade, uint256 _fee, address _to ) external payable; function swapNoSplitToETH( Trade calldata _trade, uint256 _fee, address _to ) external; function swapNoSplitWithPermit( Trade calldata _trade, uint256 _fee, address _to, uint256 _deadline, uint8 _v, bytes32 _r, bytes32 _s ) external; function swapNoSplitToETHWithPermit( Trade calldata _trade, uint256 _fee, address _to, 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.recipients, _queries.gasEstimate); } /** * Appends new elements to the end of Offer struct */ function addToTail( Offer memory _queries, uint256 _amount, address _adapter, address _recipient, 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.recipients = bytes.concat(_queries.recipients, _recipient.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.recipients.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, address recipient, 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.recipients = bytes.concat(abi.encodePacked(offer.recipients), recipient.toBytes()).toAddresses(); offer.gasEstimate += gasEstimate; } /** * Appends new elements to the beginning of FormattedOffer */ function addToHead( FormattedOffer memory offer, uint256 amountOut, address wrapper, address tokenOut, address recipient, 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.path = bytes.concat(recipient.toBytes(), abi.encodePacked(offer.recipients)).toAddresses(); offer.gasEstimate += gasEstimate; } function getAmountOut(FormattedOffer memory offer) internal pure returns (uint256) { return offer.amounts[offer.amounts.length - 1]; } }
{ "optimizer": { "enabled": true, "runs": 10000, "details": { "yulDetails": { "optimizerSteps": "u" } } }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address[]","name":"_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":"address[]","name":"_trustedTokens","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":"address[]","name":"recipients","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":"address[]","name":"_trustedTokens","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":"address[]","name":"recipients","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"},{"internalType":"address","name":"","type":"address"}],"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":"recipient","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":"recipient","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":"address[]","name":"recipients","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"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":"address[]","name":"recipients","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"swapNoSplitFromETH","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":"address[]","name":"recipients","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"swapNoSplitToETH","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":"address[]","name":"recipients","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"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":"swapNoSplitToETHWithPermit","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":"address[]","name":"recipients","type":"address[]"}],"internalType":"struct Trade","name":"_trade","type":"tuple"},{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"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
60a06040523462000061575b620000236200001962000262565b92919091620002cb565b6040516142c962000cc18239608051818181610faa015281816127e60152818161365d015281816136af015281816137de015261383c01526142c990f35b6200006a600080fd5b6200000b565b600080fd5b50634e487b7160e01b600052604160045260246000fd5b90601f01601f191681019081106001600160401b03821117620000ae57604052565b620000b862000075565b604052565b90620000d4620000cc60405190565b92836200008c565b565b60209081906001600160401b038111620000ef57020190565b620000f962000075565b020190565b6001600160a01b031690565b90565b6001600160a01b0381165b036200007057565b90505190620000d4826200010d565b90929192620001486200014282620000d6565b620000bd565b93818552602080860192028301928184116200018b575b915b8383106200016f5750505050565b602080916200017f848662000120565b81520192019162000161565b62000194600080fd5b6200015f565b906200010a9181601f82011215620001b9575b6020815191016200012f565b620001c2600080fd5b620001ad565b60808183031262000253575b8051620001f59083906001600160401b03811162000244575b83016200019a565b926200010a6200021b84602085015160018060401b03811162000235575b85016200019a565b936200022b816040860162000120565b9360600162000120565b6200023e600080fd5b62000213565b6200024d600080fd5b620001ed565b6200025c600080fd5b620001d4565b6200028562004faa803803806200027981620000bd565b928339810190620001c8565b90919293565b90600019905b9181191691161790565b6200010a6200010a6200010a9290565b90620002bf6200010a620002c7926200029b565b82546200028b565b9055565b906200030f92620003036200030992620002e462000314565b620002f260006001620002ab565b620002fd876200052c565b62000769565b620008a9565b620007d0565b608052565b620000d4620000d46200032e565b6200010a60006200029b565b620000d43362000348816200034262000322565b62000359565b60008051602062004f8a8339815191525b90620000d491620003d2565b905b600052602052604060002090565b6200010a90620000fe906001600160a01b031682565b6200010a9062000375565b6200010a906200038b565b90620003679062000396565b9060ff9062000291565b90620003ca6200010a620002c792151590565b8254620003ad565b90620003e7620003e3828462000461565b1590565b620003f0575050565b6200041660016200041083600062000409878262000365565b01620003a1565b620003b7565b33906200045062000449620004497f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9590565b9262000396565b926200045b60405190565b600090a4565b6200010a916200047991620004096000918262000365565b5460ff1690565b0190565b156200048c57565b60405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201526734b73a30b4b732b960c11b6064820152608490fd5b0390fd5b620000d490620005116200050b335b60008051602062004f8a83398151915262000461565b62000484565b620000d490620005218162000396565b6000199190620009b2565b620000d490620004e6565b620000d4906200054b6200050b33620004f5565b62000721565b90620005746200056d62000563845190565b8084529260200190565b9260200190565b9060005b818110620005865750505090565b909192620005ae620005a760019286516001600160a01b0316815260200190565b9460200190565b92910162000578565b60208082526200010a9291019062000551565b9160001960089290920291821b911b62000291565b9190620005f46200010a620002c7936200029b565b908354620005ca565b620000d491600091620005df565b81811062000617575050565b80620006276000600193620005fd565b016200060b565b90918281106200063d57505050565b620000d4929062000655905b92600052602060002090565b90810191016200060b565b90620000d49168010000000000000000821162000684575b8054908281556200062e565b6200068e62000075565b62000678565b6001620006c862000649620006a7855190565b94838060401b03861162000705575b620006c2868662000660565b60200190565b92049160005b838110620006dc5750505050565b6001906020620006f76200010a86516001600160a01b031690565b9401938184015501620006ce565b6200070f62000075565b620006b6565b90620000d49162000694565b620000d4907f658ff1688002926d8f426cb10c052ec29003f50042df9652d8613484c1a586476200075160405190565b806200075e8482620005b7565b0390a1600362000715565b620000d49062000537565b620000d490620007886200050b33620004f5565b620000d4907febf7325f48e05e5e38809c69f8b02a7c907ed31d8768e6c2d841b1296a9225fe620007b860405190565b80620007c58482620005b7565b0390a1600462000715565b620000d49062000774565b620000d490620007ef6200050b33620004f5565b62000852565b6200010a90620000fe565b6200010a9054620007f5565b6001600160a01b0391821681529116602082015260400190565b906001600160a01b039062000291565b906200084a6200010a620002c79262000396565b825462000826565b620000d49062000863600262000800565b817fb2c853ac4d80d18d058c43d8018d077a036e542a79acae1647f5ad2a8c76f4e2916200089e6200089460405190565b928392836200080c565b0390a1600262000836565b620000d490620007db565b8062000118565b90505190620000d482620008b4565b906200010a9160208183031215620008bb57620008e5600080fd5b620008bb565b506040513d6000823e3d90fd5b156200090057565b60405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608490fd5b62000987620009816200010a9263ffffffff1690565b60e01b90565b6001600160e01b03191690565b6001600160a01b039091168152604081019291620000d49160200152565b62000a2260049262000a12620000d495620009e7600084620009d4826200029b565b841491821562000a28575b5050620008f8565b620009f663095ea7b36200096b565b9262000a0160405190565b968794602086019081520162000994565b602082018103825203836200008c565b62000c50565b909150602062000a388962000396565b63dd62ed3e9062000a6962000a4d3062000396565b9262000a7562000a5c60405190565b9788958694859460e01b90565b8452600484016200080c565b03915afa91821562000ae9575b60009262000aa8575b5062000a9b62000a9f916200029b565b9190565b148438620009df565b62000a9f91925062000ad862000a9b9160203d811162000ae1575b62000acf81836200008c565b810190620008ca565b92915062000a8b565b503d62000ac3565b62000af3620008eb565b62000a82565b60209062000480906001600160401b03811162000b1a57601f01601f191690565b62000b2462000075565b601f01601f191690565b9062000b3e620001428362000af9565b918252565b3d1562000b605762000b553d62000b2e565b903d6000602084013e565b606090565b1562000b6d57565b60405162461bcd60e51b815280620004e2600482016020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b80151562000118565b90505190620000d48262000bb7565b906200010a916020818303121562000bc05762000bea600080fd5b62000bc0565b1562000bf857565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b60009162000c5f839262000396565b9082602082019151925af162000c7f62000c7862000b43565b9162000b65565b805162000c9162000a9b60006200029b565b1162000c9a5750565b62000cba81602062000cae620000d4945190565b81830101910162000bcf565b62000bf056fe6080604052600436101561001e575b361561001c5761001c600080fd5b005b60003560e01c8062b99e361461032957806301ffc9a714610320578063248a9ca3146103175780632f2ff15d1461030e57806331ac99201461030557806336568abe146102fc5780633a9a4081146102f35780633cf57ac7146102ea578063414cff85146102e157806352a52ab0146102d85780636b453c1f146102cf57806376c7a3c7146102c657806376ebe69c146102bd5780637c7a561b146102b4578063809356aa146102ab57806383637d14146102a25780638980f11f146102995780638bb9c5bf1461029057806391d148541461028757806392f5d88a1461027e578063952e901214610275578063a0cf0aea1461026c578063a217fddf14610263578063a3f4df7e1461025a578063aede369314610251578063b381cf4014610248578063b9a89ca31461023f578063befe980314610236578063c3accd481461022d578063c8a3a5c614610224578063ce6e28f21461021b578063d547741f14610212578063d73792a914610209578063d8baf7cf14610200578063dd8544b3146101f7578063dede7f15146101ee578063f2fde38b146101e5578063f6ee13a6146101dc5763f87422540361000e576101d7611424565b61000e565b506101d76113f3565b506101d7611344565b506101d7611319565b506101d76112bd565b506101d7611296565b506101d761126c565b506101d7611231565b506101d7611209565b506101d76111e2565b506101d76111bb565b506101d76111a6565b506101d761116c565b506101d7610f93565b506101d7610f6c565b506101d7610f36565b506101d7610e08565b506101d7610dbf565b506101d7610d6d565b506101d7610d27565b506101d7610bda565b506101d7610bb3565b506101d7610b8b565b506101d7610b32565b506101d7610a93565b506101d7610a06565b506101d76109db565b506101d76109b1565b506101d7610968565b506101d7610921565b506101d761085d565b506101d761082f565b506101d7610748565b506101d7610576565b506101d761054f565b506101d7610522565b506101d76104a0565b506101d7610434565b506101d76103a5565b600080fd5b600091031261034257565b61034a600080fd5b565b61036e916008021c5b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b9061036e915461034c565b61036e60006002610371565b61039190610355565b9052565b60208101929161034a9190610388565b50346103d2575b6103b7366004610337565b6103ce6103c261037c565b60405191829182610395565b0390f35b6103da600080fd5b6103ac565b7fffffffff0000000000000000000000000000000000000000000000000000000081165b0361033257565b9050359061034a826103df565b9061036e916020818303121561040a5761042f600080fd5b61040a565b5034610463575b6103ce61045161044c366004610417565b61146c565b60405191829182901515815260200190565b61046b600080fd5b61043b565b80610403565b9050359061034a82610470565b9061036e91602081830312156104765761049b600080fd5b610476565b50346104ce575b6103ce6104bd6104b8366004610483565b61159c565b6040515b9182918290815260200190565b6104d6600080fd5b6104a7565b61040381610355565b9050359061034a826104db565b919061036e90604084820312610515575b61050c8185610476565b936020016104e4565b61051d600080fd5b610502565b5034610542575b61053d6105373660046104f1565b906115db565b604051005b61054a600080fd5b610529565b5034610569575b61053d610564366004610483565b611ff7565b610571600080fd5b610556565b5034610591575b61053d61058b3660046104f1565b906117a4565b610599600080fd5b61057d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761063657604052565b61063e6105c6565b604052565b9061034a61065060405190565b92836105f6565b6020809167ffffffffffffffff811161066f57020190565b6106776105c6565b020190565b9092919261069161068c82610657565b610643565b93818552602080860192028301928184116106cf575b915b8383106106b65750505050565b602080916106c484866104e4565b8152019201916106a9565b6106d7600080fd5b6106a7565b9061036e9181601f820112156106f8575b60208135910161067c565b610700600080fd5b6106ed565b9061036e9160208183031261073b575b80359067ffffffffffffffff821161072e575b016106dc565b610736600080fd5b610728565b610743600080fd5b610715565b5034610762575b61053d61075d366004610705565b611f33565b61076a600080fd5b61074f565b908160a091031261077d5790565b61036e600080fd5b60ff8116610403565b9050359061034a82610785565b60e081830312610822575b6107c382823567ffffffffffffffff8111610815575b830161076f565b926107d18360208401610476565b926107df81604085016104e4565b926107ed8260608301610476565b9261036e6107fe846080850161078e565b9361080c8160a08601610476565b9360c001610476565b61081d600080fd5b6107bc565b61082a600080fd5b6107a6565b5034610850575b61053d61084436600461079b565b95949094939193613a25565b610858600080fd5b610836565b503461087e575b61053d61087236600461079b565b9594909493919361395a565b610886600080fd5b610864565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6108db6001916108c9815490565b8410156108e457600052602060002090565b91020190600090565b6108ec61088b565b600052602060002090565b60036000610903825490565b83101561091e575061036e91610918916108bb565b90610371565b80fd5b503461093e575b6103ce6103c2610939366004610483565b6108f7565b610946600080fd5b610928565b9061036e91602081830312156104e457610963600080fd5b6104e4565b5034610982575b61053d61097d36600461094b565b613a87565b61098a600080fd5b61096f565b61036e916008021c81565b9061036e915461098f565b61036e6000600161099a565b50346109ce575b6109c3366004610337565b6103ce6104bd6109a5565b6109d6600080fd5b6109b8565b50346109f9575b6109ed366004610337565b6103ce6104bd60035490565b610a01600080fd5b6109e2565b5034610a24575b610a18366004610337565b6103ce6104bd60045490565b610a2c600080fd5b610a0d565b608081830312610a6e575b610a468282610476565b9261036e610a5784602085016104e4565b93610a6581604086016104e4565b9360600161078e565b610a76600080fd5b610a3c565b90815260408101929161034a916020905b0190610388565b5034610ac7575b610ab1610aa8366004610a31565b92919091612148565b906103ce610abe60405190565b92839283610a7b565b610acf600080fd5b610a9a565b9091606082840312610b25575b61036e610b0184843567ffffffffffffffff8111610b18575b850161076f565b93610b0f8160208601610476565b936040016104e4565b610b20600080fd5b610afa565b610b2d600080fd5b610ae1565b5034610b4d575b61053d610b47366004610ad4565b916137a4565b610b55600080fd5b610b39565b919061036e90604084820312610b7e575b610b7581856104e4565b93602001610476565b610b86600080fd5b610b6b565b5034610ba6575b61053d610ba0366004610b5a565b90613bc9565b610bae600080fd5b610b92565b5034610bcd575b61053d610bc8366004610483565b613adb565b610bd5600080fd5b610bba565b5034610bf8575b6103ce610451610bf23660046104f1565b9061156c565b610c00600080fd5b610be1565b909182601f83011215610c44575b602082359267ffffffffffffffff8411610c37575b01926020830284011161034257565b610c3f600080fd5b610c28565b610c4c600080fd5b610c13565b608081830312610cb3575b610c668282610476565b92610ca2610c7784602085016104e4565b93610c8581604086016104e4565b9360608101359067ffffffffffffffff8211610ca6575b01610c05565b9091565b610cae600080fd5b610c9c565b610cbb600080fd5b610c5c565b9060808061034a93610cda60008201516000860190610388565b610cec60208201516020860190610388565b610cfe60408201516040860190610388565b610d1060608201516060860190610388565b0151910152565b60a08101929161034a9190610cc0565b5034610d54575b6103ce610d48610d3f366004610c51565b93929092612295565b60405191829182610d17565b610d5c600080fd5b610d2e565b60046000610903825490565b5034610d8a575b6103ce6103c2610d85366004610483565b610d61565b610d92600080fd5b610d74565b61035561036e61036e9290565b61036e90610d97565b61036e6000610da4565b61036e610dad565b5034610ddc575b610dd1366004610337565b6103ce6103c2610db7565b610de4600080fd5b610dc6565b61036e61036e61036e9290565b61036e6000610de9565b61036e610df6565b5034610e25575b610e1a366004610337565b6103ce6104bd610e00565b610e2d600080fd5b610e0f565b610e6f60209167ffffffffffffffff8111610e7357601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b0190565b61059e6105c6565b90610e8861068c83610e32565b918252565b610e976010610e7b565b7f43616d656c6f7459616b526f7574657200000000000000000000000000000000602082015290565b61036e610e8d565b61036e610ec0565b61036e610ec8565b60005b838110610eeb5750506000910152565b8181015183820152602001610edb565b610f1c61059e602093610e6f93610f10815190565b80835293849260200190565b95869101610ed8565b602080825261036e92910190610efb565b5034610f5f575b610f48366004610337565b6103ce610f53610ed0565b60405191829182610f25565b610f67600080fd5b610f3d565b5034610f86575b61053d610f81366004610483565b613c2e565b610f8e600080fd5b610f73565b5034610fce575b610fa5366004610337565b6103ce7f00000000000000000000000000000000000000000000000000000000000000006103c2565b610fd6600080fd5b610f9a565b919060a083820312611048575b610ff28184610476565b9261100082602083016104e4565b9261036e61101184604085016104e4565b9361103281606086013567ffffffffffffffff811161103b575b86016106dc565b93608001610476565b611043600080fd5b61102b565b611050600080fd5b610fe8565b9061107561106e611064845190565b8084529260200190565b9260200190565b9060005b8181106110865750505090565b9091926110a361109c6001928651815260200190565b9460200190565b929101611079565b90610e6f81602093610388565b906110c761106e611064845190565b9060005b8181106110d85750505090565b9091926110eb61109c60019286516110ab565b9291016110cb565b9061036e9060808061115361114161112f61111d60a0870160008a015188820360008a0152611055565b602089015187820360208901526110b8565b604088015186820360408801526110b8565b606087015185820360608701526110b8565b940151910152565b602080825261036e929101906110f3565b5034611199575b6103ce61118d611184366004610fdb565b9392909261288d565b6040519182918261115b565b6111a1600080fd5b611173565b5061053d6111b5366004610ad4565b91613625565b50346111d5575b61053d6111d036600461094b565b6120c6565b6111dd600080fd5b6111c2565b50346111fc575b61053d6111f7366004610705565b611ed7565b611204600080fd5b6111e9565b5034611224575b61053d61121e366004610ad4565b91612e11565b61122c600080fd5b611210565b503461124c575b61053d6112463660046104f1565b90611728565b611254600080fd5b611238565b61036e612710610de9565b61036e611259565b5034611289575b61127e366004610337565b6103ce6104bd611264565b611291600080fd5b611273565b50346112b0575b61053d6112ab36600461094b565b613ab1565b6112b8600080fd5b61129d565b50346112d7575b61053d6112d236600461094b565b611ccf565b6112df600080fd5b6112c4565b909160608284031261130c575b61036e6112fe8484610476565b93610b0f81602086016104e4565b611314600080fd5b6112f1565b5034611337575b6103ce610d486113313660046112e4565b916123f9565b61133f600080fd5b611320565b503461135e575b61053d61135936600461094b565b613ae5565b611366600080fd5b61134b565b909160c0828403126113e6575b6113828383610476565b9261139081602085016104e4565b9261139e82604083016104e4565b9261036e6113c284606085013567ffffffffffffffff81116113d9575b85016106dc565b936113d08160808601610476565b9360a001610476565b6113e1600080fd5b6113bb565b6113ee600080fd5b611378565b5034611417575b6103ce61118d61140b36600461136b565b949390939291926125e8565b61141f600080fd5b6113fa565b503461145f575b611436366004610337565b6103ce7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab956104bd565b611467600080fd5b61142b565b7f7965db0b000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216149081156114bc575090565b61036e91507fffffffff00000000000000000000000000000000000000000000000000000000167f01ffc9a7000000000000000000000000000000000000000000000000000000001490565b905b600052602052604060002090565b61035561036e61036e9273ffffffffffffffffffffffffffffffffffffffff1690565b61036e90611518565b61036e9061153b565b9061150a90611544565b61036e905b60ff1690565b61036e9054611557565b61036e916115869161158060009182611508565b0161154d565b611562565b61036e9081565b61036e905461158b565b60016115b561036e926115ad600090565b506000611508565b01611592565b9061034a916115d16115cc8261159c565b6115e5565b9061034a916117f8565b9061034a916115bb565b61034a903390611681565b61036e90610de9565b610e6f6116119260209261160b815190565b94859290565b93849101610ed8565b61165861036e9392611652611652937f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260170190565b906115f9565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000815260110190565b9061169361168f828461156c565b1590565b61169b575050565b6117099161036e6116b76116b16116f194611bc4565b926115f0565b6116cc6020916116c683610de9565b90611a2a565b926116e56116d960405190565b9485938401928361161a565b908103825203826105f6565b60405191829162461bcd60e51b835260048301610f25565b0390fd5b9061034a9161171e6115cc8261159c565b9061034a9161186e565b9061034a9161170d565b1561173957565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608490fd5b61034a91906117c96117ba33610355565b610355565b6117c384610355565b14611732565b61186e565b9060ff905b9181191691161790565b906117ed61036e6117f492151590565b82546117ce565b9055565b9061180661168f828461156c565b61180e575050565b61182860016118238360006115808782611508565b6117dd565b339061185e6118586118587f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9590565b92611544565b9261186860405190565b600090a4565b90611879818361156c565b611881575050565b611895600061182383826115808782611508565b339061185e6118586118587ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9590565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190611900565b9290565b9180830292818404149015171561191357565b61034a6118c5565b9190820180921161191357565b369037565b9061034a61194361193d84610e7b565b93610e32565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401611928565b90600160209161197c845190565b81101561198a575b02010190565b61199261088b565b611984565b60019080156119a4570390565b6119ac6118c5565b0390565b61155c61036e61036e9290565b61036e906119d56119d161036e9460ff1690565b9190565b901c90565b156119e157565b60405162461bcd60e51b815280611709600482016020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b9190600290611a5b611a56611a4783611a4286610de9565b6118f5565b611a5085610de9565b9061191b565b61192d565b916000916030611a73611a6d85610de9565b8661196e565b53611ac7611abe7f780000000000000000000000000000000000000000000000000000000000000092611a426001958695881a611ab8611ab288610de9565b8b61196e565b53610de9565b611a5083610de9565b915b611aea575b505061036e9293611ae46119d161036e93610de9565b146119da565b9094611af582610de9565b861115611b8157611b6e611b688392611b4b611b2e7f303132333435363738396162636465660000000000000000000000000000000090565b611b38600f610de9565b83166010811015611b74575b1a60f81b90565b861a611b578a8961196e565b53611b6260046119b0565b906119bd565b96611997565b91611ac9565b611b7c61088b565b611b44565b94611ace565b61036e61036e61036e9273ffffffffffffffffffffffffffffffffffffffff1690565b61036e60146119b0565b61036e61036e61036e9260ff1690565b611be1611bdc61036e92611bd6606090565b5061153b565b611b87565b6116c6611bec611baa565b611bb4565b15611bf857565b60405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201527f696e7461696e65720000000000000000000000000000000000000000000000006064820152608490fd5b61034a90611c9a611c95335b7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab9561156c565b611bf1565b61034a90611ca781611544565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91613da0565b61034a90611c63565b61034a90611ce8611c9533611c6f565b611e94565b90611cfc61106e611064845190565b9060005b818110611d0d5750505090565b909192611d2061109c60019286516110ab565b929101611d00565b602080825261036e92910190611ced565b919060086117d3910291611d6c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b9190611d8261036e6117f493610de9565b908354611d39565b61034a91600091611d71565b818110611da1575050565b80611daf6000600193611d8a565b01611d96565b9091828110611dc357505050565b61034a9290611dd9905b92600052602060002090565b9081019101611d96565b9061034a91680100000000000000008211611e04575b805490828155611db5565b611e0c6105c6565b611df9565b61036e9051610355565b6001611e4c611dcd611e2b855190565b9467ffffffffffffffff8611611e7d575b611e468686611de3565b60200190565b92049160005b838110611e5f5750505050565b6001906020611e7061036e86611e11565b9401938184015501611e52565b611e856105c6565b611e3c565b9061034a91611e1b565b61034a907f658ff1688002926d8f426cb10c052ec29003f50042df9652d8613484c1a58647611ec260405190565b80611ecd8482611d28565b0390a16003611e8a565b61034a90611cd8565b61034a90611ef0611c9533611c6f565b61034a907febf7325f48e05e5e38809c69f8b02a7c907ed31d8768e6c2d841b1296a9225fe611f1e60405190565b80611f298482611d28565b0390a16004611e8a565b61034a90611ee0565b61034a90611f4c611c9533611c6f565b611fa7565b90815260408101929161034a9160200152565b0152565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff906117d3565b90611fa061036e6117f492610de9565b8254611f68565b61034a90611fb56001611592565b817f4bb8a6184424e4bb853a4836042f5a726e4e710873989bfc6abdab19966f5b7091611fed611fe460405190565b92839283611f51565b0390a16001611f90565b61034a90611f3c565b61034a90612010611c9533611c6f565b612076565b61036e90610355565b61036e9054612015565b91602061034a929493610a8c60408201966000830190610388565b9073ffffffffffffffffffffffffffffffffffffffff906117d3565b9061206f61036e6117f492611544565b8254612043565b61034a90612084600261201e565b817fb2c853ac4d80d18d058c43d8018d077a036e542a79acae1647f5ad2a8c76f4e2916120bc6120b360405190565b92839283612028565b0390a1600261205f565b61034a90612000565b9050519061034a82610470565b9050519061034a826104db565b919061036e9060408482031261210d575b61210481856120cf565b936020016120dc565b612115600080fd5b6120fa565b90815260608101939261034a929091604091610a8c905b6020830190610388565b506040513d6000823e3d90fd5b9092604090949294612158600090565b956121996000966121a261217c612177612177610918600498896108bb565b611544565b9363ef99893a9261218c60405190565b9889978896879660e01b90565b8652850161211a565b03915afa806000809390926121df575b506121d957505060016121c157565b9150506000906119d16121d383610da4565b92610de9565b93509150565b909250612203915060403d811161220a575b6121fb81836105f6565b8101906120e9565b91386121b2565b503d6121f1565b61036e60a0610643565b612223612211565b906000825260208080808086016000815201600081520160005b8152016000905250565b61036e61221b565b60019060ff1660ff8114612261570190565b610e6f6118c5565b9160209181101561227957020190565b61067761088b565b3561036e81610785565b9061039190610355565b90919294936122a2612247565b506122ab612247565b9360005b826122b982611bb4565b10156123ef5760048460406122ec6109186122e66122e18e8a6122db8a611bb4565b91612269565b612281565b856108bb565b926122f961217785611544565b61219963ef99893a61230f898d61218c60405190565b03915afa600091829190816123cc575b5061233657505050612331905b61224f565b6122af565b600092612342846119b0565b60ff86161480156123b6575b612360575b505050506123319061224f565b6123319499506123ac929161238261238b9261237a612211565b96870161228b565b6020850161228b565b612398886040850161228b565b6123a5856060850161228b565b6080830152565b9590388080612353565b506123c561036e60808c015190565b831161234e565b9092506123e7915060403d811161220a576121fb81836105f6565b90913861231f565b5093955050505050565b90612402612247565b5061240b612247565b9160005b600461241c61036e825490565b61242583611bb4565b101561252b5782604061243b61091885856108bb565b9261244861217785611544565b61219963ef99893a61245e8c8b61218c60405190565b03915afa60009182919081612508575b5061248a5750505061248590600161232c5761224f565b61240f565b600092612496846119b0565b60ff86161480156124f2575b6124b4575b505050506124859061224f565b6124859497506124e892916123826124ce9261237a612211565b6124db866040850161228b565b6123a5886060850161228b565b93903880806124a7565b5061250161036e60808a015190565b83116124a2565b909250612523915060403d811161220a576121fb81836105f6565b90913861246e565b50505050905090565b61253c612211565b9060608252602080808080860160608152016060815201606061223d565b61036e612534565b1561256957565b60405162461bcd60e51b815260206004820152601c60248201527f59616b526f757465723a20496e76616c6964206d61782d7374657073000000006044820152606490fd5b90610e8861068c83610657565b9061034a6119436125cb846125ae565b93610657565b906020809161197c845190565b61036e6000610e7b565b9290949391956125f661255a565b50600061260281610de9565b84118061276c575b61261390612562565b61261d8786613ff1565b958861262883610de9565b82111561275c57612638916127d6565b600396612643885490565b9561265d612658612652885190565b8961191b565b6125bb565b9a61266785610de9565b8c898210156126a0579061269561269b92612690838f6109188261268a926108bb565b926125d1565b61228b565b60010190565b612667565b505091939597999092949698506126b686610de9565b6126c161036e8a5190565b8110156126fc57806126958b6126908f6126f1858f6126e66126f7996126eb926125d1565b611e11565b9461191b565b906125d1565b6126b6565b50909193959992949750612714965061036e986129c7565b9061272160208301515190565b61272d6119d183610de9565b14612739575b5061413a565b6127479082016103916125de565b612756604082016103916125de565b38612733565b505061276781610de9565b612638565b5061261361277a6005610de9565b8510905061260a565b9190820391821161191357565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b81156127ca570490565b6127d2612790565b0490565b90919061282560009360606002917f000000000000000000000000000000000000000000000000000000000000000061281f612819670de0b6b3a7640000610de9565b94610de9565b9361288d565b6040810151519060009161283b6119d184610de9565b0361284557505050565b61036e93945061287661287a9392611a4292016126f1612866825192515190565b6128706001610de9565b90612783565b5190565b612887633b9aca00610de9565b906127c0565b91909261289861255a565b506000956128a587610de9565b861180612993575b6128b690612562565b6128c08585613ff1565b946003976128cc895490565b956128db612658612652875190565b976128e583610de9565b8881101561290c57806126958b6126908f9461268a61091882612907986108bb565b6128e5565b509193959890929496995061292084610de9565b61292b61036e895190565b81101561296057806126958c6126906129558461294f6126e68f9861295b996125d1565b9361191b565b8d6125d1565b612920565b509193969092955061298394985061036e9761297b87610de9565b9788956129c7565b9161272d61036e60208501515190565b506128b66129a16005610de9565b871090506128ad565b9061036e91602081830312156120cf576129c2600080fd5b6120cf565b929093959194956129d661255a565b506129e08761402d565b9182976129eb600090565b9586906000906129fa82610de9565b881196612a088c8c846123f9565b906080820191612a16835190565b612a226119d187610de9565b11612d50575b505050600199612a378b610de9565b871180612d16575b612a53575b50505050505050505050505090565b908291612a618c9594610de9565b945b612a6e575b50612a44565b612a7961036e885190565b851015612d11578c94612a926117b56126e6838b6125d1565b612a9b83610355565b14612d02578a8a8a8a612abb612ab46126e687846125d1565b87896123f9565b9960808b019a612ac98c5190565b612ad56119d18c610de9565b14612ced57612ae38d61402d565b94612c47575b8b6128768c8c612b419a9b9c9d9e9f94612b0f612b07612b2e975190565b928201611e11565b612b276060612b2060208501611e11565b9301611e11565b928b6140c3565b612b3b6126e689856125d1565b906129c7565b8d612b57612b516117b58461427b565b91610355565b1480612c27575b612b75575b506001015b9a5b9a939291908b612a63565b9a8b919e91608081018c612b87825190565b916080860192612b9b6119d161036e865190565b11612bc4575b505050612b689250612bbc9150805160409091015151015190565b9a9d90612b63565b84612c01612bf261287a6119d195612bec612c0698612870612be761036e995190565b915190565b906118f5565b95805160409091015151015190565b612783565b11612c14578b818c81612ba1565b9a509c612c219060010190565b9a612b6a565b508b612c416119d16118fc84805160409091015151015190565b11612b5e565b899b8a9b5061287682612c886020612c70612b419c9d9e9f61217761217791612b2e9901611e11565b6369cff80d90612c7f60405190565b93849260e01b90565b825260049082905afa908115612ce0575b600091612cb2575b509d509250509b9998979650612ae9565b612cd3915060203d8111612cd9575b612ccb81836105f6565b8101906129aa565b38612ca1565b503d612cc1565b612ce861213b565b612c99565b505050505050612c2191929394955060010190565b612c2191929394955060010190565b612a68565b50612d30612d2660208701515190565b6128876020610de9565b612d496119d161036e612d436002610de9565b8b612783565b1115612a3f565b9091929a5088612da0575b84839261287692612d6d612d97965190565b612d78888301611e11565b90612d916060612d8a60208601611e11565b9401611e11565b936140c3565b97388080612a28565b612d979291945080612dc16020612c70612177612177896128769701611e11565b825260049082905afa908115612e04575b600091612de6575b50959293509050612d5b565b612dfe915060203d8111612cd957612ccb81836105f6565b38612dda565b612e0c61213b565b612dd2565b90612e1e92913390612f91565b50565b3561036e81610470565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe13682900301821215612e8f575b01602081359167ffffffffffffffff8311612e82575b0191602082023603831361034257565b612e8a600080fd5b612e72565b612e97600080fd5b612e5c565b3561036e816104db565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612261570190565b61039190610de9565b9095949261034a94612f15610a8c92612f0b608096612f0160a088019c6000890152565b6020870190612ed4565b6040850190610388565b6060830190610388565b15612f2657565b60405162461bcd60e51b815260206004820152602560248201527f59616b526f757465723a20496e73756666696369656e74206f7574707574206160448201527f6d6f756e740000000000000000000000000000000000000000000000000000006064820152608490fd5b92939183916131079161303c90612fa785612e21565b90612fb26000610de9565b811180156134c9575b61347a575b506020612feb612177612177612fe6612fdc60408b018b612e2b565b6122db6000610de9565b612e9c565b612ffe612fe6612fdc60808a018a612e2b565b9061300860405190565b948592839182917f70a08231000000000000000000000000000000000000000000000000000000005b835260048301610395565b03915afa91821561346d575b60009261344b575b508192613085925061306b612fe6612fdc6040890189612e2b565b9061307f612fe6612fdc60808a018a612e2b565b91613573565b6130ed60206130a3612177612177612fe6612fdc60408a018a612e2b565b6130b6612fe6612fdc6080890189612e2b565b906130c060405190565b938492839182917f70a0823100000000000000000000000000000000000000000000000000000000613031565b03915afa908115613321575b600091613303575b50612783565b93613133612fe661311b6040850185612e2b565b6122db61286661312e6040890189612e2b565b905090565b9261313e6000610de9565b955b606084019061315561036e61312e8488612e2b565b8810156133c25790879161317261036e61286661312e858a612e2b565b8310156133ba578561319a612fe661318d6080840184612e2b565b6122db6126526001610de9565b915b6131c8612177612177612fe66131b56040870187612e2b565b6122db6131c26001610de9565b8c61191b565b9360206131d460405190565b9586907f70a0823100000000000000000000000000000000000000000000000000000000825281806132098960048301610395565b03915afa9485156133ad575b60009561336e575b50926132ef612177612177612fe6896122db6132a3896000806132fd9f9b6132f79f9e8f6130ed9f60209f8f93613270612177612177612fe68561326a6132d4968d996132c99b50612e2b565b90612269565b94896132b0612fe663eab90da6956122db6132a3613298612fe68461326a60408a018a612e2b565b956040810190612e2b565b919092611a506001610de9565b90873b15613361575b6040519a8b998a98899760e01b90565b875260048701612edd565b03925af18015613354575b61332e575b506040810190612e2b565b6040516130c0565b96612ea6565b95613140565b61331b915060203d8111612cd957612ccb81836105f6565b38613101565b61332961213b565b6130f9565b6133479060005b61333f81836105f6565b810190610337565b386132e4565b503d613335565b61335c61213b565b6132df565b613369600080fd5b6132b9565b839550868593949592819260203d81116133a6575b61338d81836105f6565b8101613398916129aa565b97509250509392919361321d565b503d613383565b6133b561213b565b613215565b85859161319c565b9594936133fd9297506134039350612fe69150612fdc906133f36133eb61036e60208401612e21565b891015612f1f565b6040810190612e2b565b92612e21565b91836134386134327f9fc8352e52998db4087d5e6e1c1aafa38788e749e5d7a24f5cb230f73795440293611544565b93611544565b93613445611fe460405190565b0390a390565b61308592506134679060203d8111612cd957612ccb81836105f6565b91613050565b61347561213b565b613048565b61348d915061348888612e21565b613533565b6134c3816134a4612fe6612fdc60408a018a612e2b565b90856134bd6134b3600261201e565b92612c018d612e21565b92613573565b38612fc0565b506134d46001611592565b6134e16119d16000610de9565b11612fbb565b156134ee57565b60405162461bcd60e51b815260206004820152601b60248201527f59616b526f757465723a20496e73756666696369656e742066656500000000006044820152606490fd5b9061356e61036e92613543600090565b5061355c61355461036e6001611592565b8410156134e7565b612bec613567611259565b9384612783565b6127c0565b9291906135826117b530611544565b61358b82610355565b146135a15761359c61034a94611544565b613cf8565b506135ae61034a93611544565b613c90565b156135ba57565b60405162461bcd60e51b815260206004820152602860248201527f59616b526f757465723a2050617468206e6565647320746f20626567696e207760448201527f69746820574554480000000000000000000000000000000000000000000000006064820152608490fd5b90612e1e929161369361368e612fe66136876136556136476040870187612e2b565b93906000946122db86610de9565b613681612b517f0000000000000000000000000000000000000000000000000000000000000000610355565b146135b3565b8301612e21565b6136a2565b61369c30611544565b90612f91565b60006136ee6136d36121777f0000000000000000000000000000000000000000000000000000000000000000611544565b63d0e30db0813b15613725575b604051948593849260e01b90565b825281600481015b03925af18015613718575b6137085750565b61034a90600061333f81836105f6565b61372061213b565b613701565b61372d600080fd5b6136e0565b1561373957565b60405162461bcd60e51b815260206004820152602660248201527f59616b526f757465723a2050617468206e6565647320746f20656e642077697460448201527f68205745544800000000000000000000000000000000000000000000000000006064820152608490fd5b6138189061034a93926138086137d6612fe66040850161312e6122db6128666137cd848a612e2b565b9390948a612e2b565b613802612b517f0000000000000000000000000000000000000000000000000000000000000000610355565b14613732565b3361381230611544565b92612f91565b6138218161382e565b613829610dad565b61389c565b60006136f6916138606121777f0000000000000000000000000000000000000000000000000000000000000000611544565b61388183632e1a7d4d833b1561388f575b6040519687958694859360e01b90565b835260048301526024820190565b613897600080fd5b613871565b916138a630611544565b6138b2612b5183610355565b036138bc57505050565b6138c76117b5610dad565b6138d084610355565b0361390a57600080935080926138e96121778394611544565b828215613901575bf1156138f957565b61034a61213b565b506108fc6138f1565b6135ae61034a93611544565b949290979695939160e08601986000870161393091610388565b6020860161393d91610388565b6040850152606084015260ff16608083015260a082015260c00152565b929561034a96612fe693966139cc6139d787959861397b6040880188612e2b565b92909661399761217761217760009c8d9b8c986122db8a610de9565b9563d505accf9333986139b4876139ad30611544565b9d01612e21565b893b15613a18575b6040519c8d9b8c9a8b9960e01b90565b895260048901613916565b03925af18015613a0b575b6139ee575b5050612e11565b81613a0492903d1061334d5761333f81836105f6565b38806139e7565b613a1361213b565b6139e2565b613a20600080fd5b6139bc565b929561034a96612fe693966139cc613a4687959861397b6040880188612e2b565b03925af18015613a7a575b613a5d575b50506137a4565b81613a7392903d1061334d5761333f81836105f6565b3880613a56565b613a8261213b565b613a51565b61034a907f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab956115db565b61034a907f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab95611728565b61034a903361058b565b61034a903390613afd613af6610df6565b91826115db565b6117a4565b61034a9190613b13611c9533611c6f565b613b64565b15613b1f57565b60405162461bcd60e51b815260206004820152601260248201527f4e6f7468696e6720746f207265636f76657200000000000000000000000000006044820152606490fd5b613b79613b716000610de9565b835b11613b18565b613b8d82613b8683611544565b3390613c90565b613bc4613bba7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa2892611544565b926104c160405190565b0390a2565b9061034a91613b02565b61034a90613be3611c9533611c6f565b613b8d6000613bfa613bf482610de9565b84613b73565b8080808086613c0b61217733611544565b828215613c25575bf1610da457613c2061213b565b610da4565b506108fc613c13565b61034a90613bd3565b613c50613c4a61036e9263ffffffff1690565b60e01b90565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b91602061034a929493611f6460408201966000830190610388565b613cd3600492613cc461034a95613caa63a9059cbb613c37565b92613cb460405190565b9687946020860190815201613c75565b602082018103825203836105f6565b613f90565b604090611f6461034a949695939661213160608401986000850190610388565b90613cd390613cc461034a95600495613d146323b872dd613c37565b93613d1e60405190565b9788956020870190815201613cd8565b15613d3557565b60405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608490fd5b613cd3600492613cc461034a95613dcd600084613dbc82610de9565b8414918215613dda575b5050613d2e565b613caa63095ea7b3613c37565b9091506020613de889611544565b63dd62ed3e90613e14613dfa30611544565b92613e1f613e0760405190565b9788958694859460e01b90565b845260048401612028565b03915afa918215613e70575b600092613e48575b506119d1613e4091610de9565b148438613dc6565b613e40919250613e686119d19160203d8111612cd957612ccb81836105f6565b929150613e33565b613e7861213b565b613e2b565b3d15613e9757613e8c3d610e7b565b903d6000602084013e565b606090565b15613ea357565b60405162461bcd60e51b815280611709600482016020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b801515610403565b9050519061034a82613eec565b9061036e9160208183031215613ef457613f19600080fd5b613ef4565b15613f2557565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608490fd5b600091613f9d8392611544565b9082602082019151925af1613fb9613fb3613e7d565b91613e9c565b8051613fc86119d16000610de9565b11613fd05750565b613fec816020613fe161034a945190565b818301019101613f01565b613f1e565b9190604061401261400061255a565b9261400b8496614017565b8452614017565b910152565b90602091614027611a5684610de9565b92830152565b61403561255a565b5061036e6000820151916123a5602082015191614082604082015161407b6140636080606086015195015190565b9561407461406f612211565b998a52565b6020890152565b6040870152565b6060850152565b6116529061036e93926115f9565b6140b7929161034a916140a960405190565b948592602084019283614089565b908103825203836105f6565b90926103919360809361034a97966140ea60408601916140e4835191614017565b90614097565b90526140ff60208501916140e4835191614017565b905261411460008401916140e4835191614017565b905261412960608301916140e4835191614017565b90520191614135835190565b61191b565b61414261255a565b5061036e6141536000830151614219565b916123a56141646020830151614190565b916140826141756040830151614190565b61407b614063608061418a6060870151614190565b95015190565b908151916141a661265860209461288786610de9565b92836141b26000610de9565b6141c961036e6141c0865190565b61288786610de9565b8110156142125761420d906142086141fe6141f86141ef6141e988610de9565b856118f5565b611a5088610de9565b87015190565b612690838a6125d1565b612ea6565b6141b2565b5093505050565b9081519161422f61265860209461288786610de9565b928361423b6000610de9565b61424961036e6141c0865190565b81101561421257614276906142086142696141f86141ef6141e988610de9565b614273838a6125d1565b52565b61423b565b604061036e91614289600090565b500151805101519056fea26469706673582212209bab7ef2e02c88142d1a19cfb4bd54703a6e2d7623fefdd4d93a123ad69be2eb64736f6c63430008110033339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab950000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000001bb7b44cc398aaa2b76ac6253f0f5634279db9d00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b5570000000000000000000000000000000000000000000000000000000000000003000000000000000000000000f05902d8eb53a354c9ddc67175df3d9bee1f95810000000000000000000000009cc2b9f9a6194c5cc827c88571e42ceaa76fdf4700000000000000000000000036049d5b4aaef6c39cd4a5bd1a2e1224f07621a20000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cf800f4948d16f23333508191b1b1591daf70438000000000000000000000000a2235d059f80e176d931ef76b6c51953eb3fbef400000000000000000000000048b62137edfa95a428d35c09e44256a739f6b557
Deployed Bytecode
0x6080604052600436101561001e575b361561001c5761001c600080fd5b005b60003560e01c8062b99e361461032957806301ffc9a714610320578063248a9ca3146103175780632f2ff15d1461030e57806331ac99201461030557806336568abe146102fc5780633a9a4081146102f35780633cf57ac7146102ea578063414cff85146102e157806352a52ab0146102d85780636b453c1f146102cf57806376c7a3c7146102c657806376ebe69c146102bd5780637c7a561b146102b4578063809356aa146102ab57806383637d14146102a25780638980f11f146102995780638bb9c5bf1461029057806391d148541461028757806392f5d88a1461027e578063952e901214610275578063a0cf0aea1461026c578063a217fddf14610263578063a3f4df7e1461025a578063aede369314610251578063b381cf4014610248578063b9a89ca31461023f578063befe980314610236578063c3accd481461022d578063c8a3a5c614610224578063ce6e28f21461021b578063d547741f14610212578063d73792a914610209578063d8baf7cf14610200578063dd8544b3146101f7578063dede7f15146101ee578063f2fde38b146101e5578063f6ee13a6146101dc5763f87422540361000e576101d7611424565b61000e565b506101d76113f3565b506101d7611344565b506101d7611319565b506101d76112bd565b506101d7611296565b506101d761126c565b506101d7611231565b506101d7611209565b506101d76111e2565b506101d76111bb565b506101d76111a6565b506101d761116c565b506101d7610f93565b506101d7610f6c565b506101d7610f36565b506101d7610e08565b506101d7610dbf565b506101d7610d6d565b506101d7610d27565b506101d7610bda565b506101d7610bb3565b506101d7610b8b565b506101d7610b32565b506101d7610a93565b506101d7610a06565b506101d76109db565b506101d76109b1565b506101d7610968565b506101d7610921565b506101d761085d565b506101d761082f565b506101d7610748565b506101d7610576565b506101d761054f565b506101d7610522565b506101d76104a0565b506101d7610434565b506101d76103a5565b600080fd5b600091031261034257565b61034a600080fd5b565b61036e916008021c5b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b9061036e915461034c565b61036e60006002610371565b61039190610355565b9052565b60208101929161034a9190610388565b50346103d2575b6103b7366004610337565b6103ce6103c261037c565b60405191829182610395565b0390f35b6103da600080fd5b6103ac565b7fffffffff0000000000000000000000000000000000000000000000000000000081165b0361033257565b9050359061034a826103df565b9061036e916020818303121561040a5761042f600080fd5b61040a565b5034610463575b6103ce61045161044c366004610417565b61146c565b60405191829182901515815260200190565b61046b600080fd5b61043b565b80610403565b9050359061034a82610470565b9061036e91602081830312156104765761049b600080fd5b610476565b50346104ce575b6103ce6104bd6104b8366004610483565b61159c565b6040515b9182918290815260200190565b6104d6600080fd5b6104a7565b61040381610355565b9050359061034a826104db565b919061036e90604084820312610515575b61050c8185610476565b936020016104e4565b61051d600080fd5b610502565b5034610542575b61053d6105373660046104f1565b906115db565b604051005b61054a600080fd5b610529565b5034610569575b61053d610564366004610483565b611ff7565b610571600080fd5b610556565b5034610591575b61053d61058b3660046104f1565b906117a4565b610599600080fd5b61057d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810190811067ffffffffffffffff82111761063657604052565b61063e6105c6565b604052565b9061034a61065060405190565b92836105f6565b6020809167ffffffffffffffff811161066f57020190565b6106776105c6565b020190565b9092919261069161068c82610657565b610643565b93818552602080860192028301928184116106cf575b915b8383106106b65750505050565b602080916106c484866104e4565b8152019201916106a9565b6106d7600080fd5b6106a7565b9061036e9181601f820112156106f8575b60208135910161067c565b610700600080fd5b6106ed565b9061036e9160208183031261073b575b80359067ffffffffffffffff821161072e575b016106dc565b610736600080fd5b610728565b610743600080fd5b610715565b5034610762575b61053d61075d366004610705565b611f33565b61076a600080fd5b61074f565b908160a091031261077d5790565b61036e600080fd5b60ff8116610403565b9050359061034a82610785565b60e081830312610822575b6107c382823567ffffffffffffffff8111610815575b830161076f565b926107d18360208401610476565b926107df81604085016104e4565b926107ed8260608301610476565b9261036e6107fe846080850161078e565b9361080c8160a08601610476565b9360c001610476565b61081d600080fd5b6107bc565b61082a600080fd5b6107a6565b5034610850575b61053d61084436600461079b565b95949094939193613a25565b610858600080fd5b610836565b503461087e575b61053d61087236600461079b565b9594909493919361395a565b610886600080fd5b610864565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6108db6001916108c9815490565b8410156108e457600052602060002090565b91020190600090565b6108ec61088b565b600052602060002090565b60036000610903825490565b83101561091e575061036e91610918916108bb565b90610371565b80fd5b503461093e575b6103ce6103c2610939366004610483565b6108f7565b610946600080fd5b610928565b9061036e91602081830312156104e457610963600080fd5b6104e4565b5034610982575b61053d61097d36600461094b565b613a87565b61098a600080fd5b61096f565b61036e916008021c81565b9061036e915461098f565b61036e6000600161099a565b50346109ce575b6109c3366004610337565b6103ce6104bd6109a5565b6109d6600080fd5b6109b8565b50346109f9575b6109ed366004610337565b6103ce6104bd60035490565b610a01600080fd5b6109e2565b5034610a24575b610a18366004610337565b6103ce6104bd60045490565b610a2c600080fd5b610a0d565b608081830312610a6e575b610a468282610476565b9261036e610a5784602085016104e4565b93610a6581604086016104e4565b9360600161078e565b610a76600080fd5b610a3c565b90815260408101929161034a916020905b0190610388565b5034610ac7575b610ab1610aa8366004610a31565b92919091612148565b906103ce610abe60405190565b92839283610a7b565b610acf600080fd5b610a9a565b9091606082840312610b25575b61036e610b0184843567ffffffffffffffff8111610b18575b850161076f565b93610b0f8160208601610476565b936040016104e4565b610b20600080fd5b610afa565b610b2d600080fd5b610ae1565b5034610b4d575b61053d610b47366004610ad4565b916137a4565b610b55600080fd5b610b39565b919061036e90604084820312610b7e575b610b7581856104e4565b93602001610476565b610b86600080fd5b610b6b565b5034610ba6575b61053d610ba0366004610b5a565b90613bc9565b610bae600080fd5b610b92565b5034610bcd575b61053d610bc8366004610483565b613adb565b610bd5600080fd5b610bba565b5034610bf8575b6103ce610451610bf23660046104f1565b9061156c565b610c00600080fd5b610be1565b909182601f83011215610c44575b602082359267ffffffffffffffff8411610c37575b01926020830284011161034257565b610c3f600080fd5b610c28565b610c4c600080fd5b610c13565b608081830312610cb3575b610c668282610476565b92610ca2610c7784602085016104e4565b93610c8581604086016104e4565b9360608101359067ffffffffffffffff8211610ca6575b01610c05565b9091565b610cae600080fd5b610c9c565b610cbb600080fd5b610c5c565b9060808061034a93610cda60008201516000860190610388565b610cec60208201516020860190610388565b610cfe60408201516040860190610388565b610d1060608201516060860190610388565b0151910152565b60a08101929161034a9190610cc0565b5034610d54575b6103ce610d48610d3f366004610c51565b93929092612295565b60405191829182610d17565b610d5c600080fd5b610d2e565b60046000610903825490565b5034610d8a575b6103ce6103c2610d85366004610483565b610d61565b610d92600080fd5b610d74565b61035561036e61036e9290565b61036e90610d97565b61036e6000610da4565b61036e610dad565b5034610ddc575b610dd1366004610337565b6103ce6103c2610db7565b610de4600080fd5b610dc6565b61036e61036e61036e9290565b61036e6000610de9565b61036e610df6565b5034610e25575b610e1a366004610337565b6103ce6104bd610e00565b610e2d600080fd5b610e0f565b610e6f60209167ffffffffffffffff8111610e7357601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01690565b0190565b61059e6105c6565b90610e8861068c83610e32565b918252565b610e976010610e7b565b7f43616d656c6f7459616b526f7574657200000000000000000000000000000000602082015290565b61036e610e8d565b61036e610ec0565b61036e610ec8565b60005b838110610eeb5750506000910152565b8181015183820152602001610edb565b610f1c61059e602093610e6f93610f10815190565b80835293849260200190565b95869101610ed8565b602080825261036e92910190610efb565b5034610f5f575b610f48366004610337565b6103ce610f53610ed0565b60405191829182610f25565b610f67600080fd5b610f3d565b5034610f86575b61053d610f81366004610483565b613c2e565b610f8e600080fd5b610f73565b5034610fce575b610fa5366004610337565b6103ce7f00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b5576103c2565b610fd6600080fd5b610f9a565b919060a083820312611048575b610ff28184610476565b9261100082602083016104e4565b9261036e61101184604085016104e4565b9361103281606086013567ffffffffffffffff811161103b575b86016106dc565b93608001610476565b611043600080fd5b61102b565b611050600080fd5b610fe8565b9061107561106e611064845190565b8084529260200190565b9260200190565b9060005b8181106110865750505090565b9091926110a361109c6001928651815260200190565b9460200190565b929101611079565b90610e6f81602093610388565b906110c761106e611064845190565b9060005b8181106110d85750505090565b9091926110eb61109c60019286516110ab565b9291016110cb565b9061036e9060808061115361114161112f61111d60a0870160008a015188820360008a0152611055565b602089015187820360208901526110b8565b604088015186820360408801526110b8565b606087015185820360608701526110b8565b940151910152565b602080825261036e929101906110f3565b5034611199575b6103ce61118d611184366004610fdb565b9392909261288d565b6040519182918261115b565b6111a1600080fd5b611173565b5061053d6111b5366004610ad4565b91613625565b50346111d5575b61053d6111d036600461094b565b6120c6565b6111dd600080fd5b6111c2565b50346111fc575b61053d6111f7366004610705565b611ed7565b611204600080fd5b6111e9565b5034611224575b61053d61121e366004610ad4565b91612e11565b61122c600080fd5b611210565b503461124c575b61053d6112463660046104f1565b90611728565b611254600080fd5b611238565b61036e612710610de9565b61036e611259565b5034611289575b61127e366004610337565b6103ce6104bd611264565b611291600080fd5b611273565b50346112b0575b61053d6112ab36600461094b565b613ab1565b6112b8600080fd5b61129d565b50346112d7575b61053d6112d236600461094b565b611ccf565b6112df600080fd5b6112c4565b909160608284031261130c575b61036e6112fe8484610476565b93610b0f81602086016104e4565b611314600080fd5b6112f1565b5034611337575b6103ce610d486113313660046112e4565b916123f9565b61133f600080fd5b611320565b503461135e575b61053d61135936600461094b565b613ae5565b611366600080fd5b61134b565b909160c0828403126113e6575b6113828383610476565b9261139081602085016104e4565b9261139e82604083016104e4565b9261036e6113c284606085013567ffffffffffffffff81116113d9575b85016106dc565b936113d08160808601610476565b9360a001610476565b6113e1600080fd5b6113bb565b6113ee600080fd5b611378565b5034611417575b6103ce61118d61140b36600461136b565b949390939291926125e8565b61141f600080fd5b6113fa565b503461145f575b611436366004610337565b6103ce7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab956104bd565b611467600080fd5b61142b565b7f7965db0b000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216149081156114bc575090565b61036e91507fffffffff00000000000000000000000000000000000000000000000000000000167f01ffc9a7000000000000000000000000000000000000000000000000000000001490565b905b600052602052604060002090565b61035561036e61036e9273ffffffffffffffffffffffffffffffffffffffff1690565b61036e90611518565b61036e9061153b565b9061150a90611544565b61036e905b60ff1690565b61036e9054611557565b61036e916115869161158060009182611508565b0161154d565b611562565b61036e9081565b61036e905461158b565b60016115b561036e926115ad600090565b506000611508565b01611592565b9061034a916115d16115cc8261159c565b6115e5565b9061034a916117f8565b9061034a916115bb565b61034a903390611681565b61036e90610de9565b610e6f6116119260209261160b815190565b94859290565b93849101610ed8565b61165861036e9392611652611652937f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260170190565b906115f9565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000815260110190565b9061169361168f828461156c565b1590565b61169b575050565b6117099161036e6116b76116b16116f194611bc4565b926115f0565b6116cc6020916116c683610de9565b90611a2a565b926116e56116d960405190565b9485938401928361161a565b908103825203826105f6565b60405191829162461bcd60e51b835260048301610f25565b0390fd5b9061034a9161171e6115cc8261159c565b9061034a9161186e565b9061034a9161170d565b1561173957565b60405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608490fd5b61034a91906117c96117ba33610355565b610355565b6117c384610355565b14611732565b61186e565b9060ff905b9181191691161790565b906117ed61036e6117f492151590565b82546117ce565b9055565b9061180661168f828461156c565b61180e575050565b61182860016118238360006115808782611508565b6117dd565b339061185e6118586118587f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9590565b92611544565b9261186860405190565b600090a4565b90611879818361156c565b611881575050565b611895600061182383826115808782611508565b339061185e6118586118587ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9590565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190611900565b9290565b9180830292818404149015171561191357565b61034a6118c5565b9190820180921161191357565b369037565b9061034a61194361193d84610e7b565b93610e32565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00160208401611928565b90600160209161197c845190565b81101561198a575b02010190565b61199261088b565b611984565b60019080156119a4570390565b6119ac6118c5565b0390565b61155c61036e61036e9290565b61036e906119d56119d161036e9460ff1690565b9190565b901c90565b156119e157565b60405162461bcd60e51b815280611709600482016020808252818101527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604082015260600190565b9190600290611a5b611a56611a4783611a4286610de9565b6118f5565b611a5085610de9565b9061191b565b61192d565b916000916030611a73611a6d85610de9565b8661196e565b53611ac7611abe7f780000000000000000000000000000000000000000000000000000000000000092611a426001958695881a611ab8611ab288610de9565b8b61196e565b53610de9565b611a5083610de9565b915b611aea575b505061036e9293611ae46119d161036e93610de9565b146119da565b9094611af582610de9565b861115611b8157611b6e611b688392611b4b611b2e7f303132333435363738396162636465660000000000000000000000000000000090565b611b38600f610de9565b83166010811015611b74575b1a60f81b90565b861a611b578a8961196e565b53611b6260046119b0565b906119bd565b96611997565b91611ac9565b611b7c61088b565b611b44565b94611ace565b61036e61036e61036e9273ffffffffffffffffffffffffffffffffffffffff1690565b61036e60146119b0565b61036e61036e61036e9260ff1690565b611be1611bdc61036e92611bd6606090565b5061153b565b611b87565b6116c6611bec611baa565b611bb4565b15611bf857565b60405162461bcd60e51b815260206004820152602860248201527f4d61696e7461696e61626c653a2043616c6c6572206973206e6f742061206d6160448201527f696e7461696e65720000000000000000000000000000000000000000000000006064820152608490fd5b61034a90611c9a611c95335b7f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab9561156c565b611bf1565b61034a90611ca781611544565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91613da0565b61034a90611c63565b61034a90611ce8611c9533611c6f565b611e94565b90611cfc61106e611064845190565b9060005b818110611d0d5750505090565b909192611d2061109c60019286516110ab565b929101611d00565b602080825261036e92910190611ced565b919060086117d3910291611d6c7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841b90565b921b90565b9190611d8261036e6117f493610de9565b908354611d39565b61034a91600091611d71565b818110611da1575050565b80611daf6000600193611d8a565b01611d96565b9091828110611dc357505050565b61034a9290611dd9905b92600052602060002090565b9081019101611d96565b9061034a91680100000000000000008211611e04575b805490828155611db5565b611e0c6105c6565b611df9565b61036e9051610355565b6001611e4c611dcd611e2b855190565b9467ffffffffffffffff8611611e7d575b611e468686611de3565b60200190565b92049160005b838110611e5f5750505050565b6001906020611e7061036e86611e11565b9401938184015501611e52565b611e856105c6565b611e3c565b9061034a91611e1b565b61034a907f658ff1688002926d8f426cb10c052ec29003f50042df9652d8613484c1a58647611ec260405190565b80611ecd8482611d28565b0390a16003611e8a565b61034a90611cd8565b61034a90611ef0611c9533611c6f565b61034a907febf7325f48e05e5e38809c69f8b02a7c907ed31d8768e6c2d841b1296a9225fe611f1e60405190565b80611f298482611d28565b0390a16004611e8a565b61034a90611ee0565b61034a90611f4c611c9533611c6f565b611fa7565b90815260408101929161034a9160200152565b0152565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff906117d3565b90611fa061036e6117f492610de9565b8254611f68565b61034a90611fb56001611592565b817f4bb8a6184424e4bb853a4836042f5a726e4e710873989bfc6abdab19966f5b7091611fed611fe460405190565b92839283611f51565b0390a16001611f90565b61034a90611f3c565b61034a90612010611c9533611c6f565b612076565b61036e90610355565b61036e9054612015565b91602061034a929493610a8c60408201966000830190610388565b9073ffffffffffffffffffffffffffffffffffffffff906117d3565b9061206f61036e6117f492611544565b8254612043565b61034a90612084600261201e565b817fb2c853ac4d80d18d058c43d8018d077a036e542a79acae1647f5ad2a8c76f4e2916120bc6120b360405190565b92839283612028565b0390a1600261205f565b61034a90612000565b9050519061034a82610470565b9050519061034a826104db565b919061036e9060408482031261210d575b61210481856120cf565b936020016120dc565b612115600080fd5b6120fa565b90815260608101939261034a929091604091610a8c905b6020830190610388565b506040513d6000823e3d90fd5b9092604090949294612158600090565b956121996000966121a261217c612177612177610918600498896108bb565b611544565b9363ef99893a9261218c60405190565b9889978896879660e01b90565b8652850161211a565b03915afa806000809390926121df575b506121d957505060016121c157565b9150506000906119d16121d383610da4565b92610de9565b93509150565b909250612203915060403d811161220a575b6121fb81836105f6565b8101906120e9565b91386121b2565b503d6121f1565b61036e60a0610643565b612223612211565b906000825260208080808086016000815201600081520160005b8152016000905250565b61036e61221b565b60019060ff1660ff8114612261570190565b610e6f6118c5565b9160209181101561227957020190565b61067761088b565b3561036e81610785565b9061039190610355565b90919294936122a2612247565b506122ab612247565b9360005b826122b982611bb4565b10156123ef5760048460406122ec6109186122e66122e18e8a6122db8a611bb4565b91612269565b612281565b856108bb565b926122f961217785611544565b61219963ef99893a61230f898d61218c60405190565b03915afa600091829190816123cc575b5061233657505050612331905b61224f565b6122af565b600092612342846119b0565b60ff86161480156123b6575b612360575b505050506123319061224f565b6123319499506123ac929161238261238b9261237a612211565b96870161228b565b6020850161228b565b612398886040850161228b565b6123a5856060850161228b565b6080830152565b9590388080612353565b506123c561036e60808c015190565b831161234e565b9092506123e7915060403d811161220a576121fb81836105f6565b90913861231f565b5093955050505050565b90612402612247565b5061240b612247565b9160005b600461241c61036e825490565b61242583611bb4565b101561252b5782604061243b61091885856108bb565b9261244861217785611544565b61219963ef99893a61245e8c8b61218c60405190565b03915afa60009182919081612508575b5061248a5750505061248590600161232c5761224f565b61240f565b600092612496846119b0565b60ff86161480156124f2575b6124b4575b505050506124859061224f565b6124859497506124e892916123826124ce9261237a612211565b6124db866040850161228b565b6123a5886060850161228b565b93903880806124a7565b5061250161036e60808a015190565b83116124a2565b909250612523915060403d811161220a576121fb81836105f6565b90913861246e565b50505050905090565b61253c612211565b9060608252602080808080860160608152016060815201606061223d565b61036e612534565b1561256957565b60405162461bcd60e51b815260206004820152601c60248201527f59616b526f757465723a20496e76616c6964206d61782d7374657073000000006044820152606490fd5b90610e8861068c83610657565b9061034a6119436125cb846125ae565b93610657565b906020809161197c845190565b61036e6000610e7b565b9290949391956125f661255a565b50600061260281610de9565b84118061276c575b61261390612562565b61261d8786613ff1565b958861262883610de9565b82111561275c57612638916127d6565b600396612643885490565b9561265d612658612652885190565b8961191b565b6125bb565b9a61266785610de9565b8c898210156126a0579061269561269b92612690838f6109188261268a926108bb565b926125d1565b61228b565b60010190565b612667565b505091939597999092949698506126b686610de9565b6126c161036e8a5190565b8110156126fc57806126958b6126908f6126f1858f6126e66126f7996126eb926125d1565b611e11565b9461191b565b906125d1565b6126b6565b50909193959992949750612714965061036e986129c7565b9061272160208301515190565b61272d6119d183610de9565b14612739575b5061413a565b6127479082016103916125de565b612756604082016103916125de565b38612733565b505061276781610de9565b612638565b5061261361277a6005610de9565b8510905061260a565b9190820391821161191357565b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b81156127ca570490565b6127d2612790565b0490565b90919061282560009360606002917f00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b55761281f612819670de0b6b3a7640000610de9565b94610de9565b9361288d565b6040810151519060009161283b6119d184610de9565b0361284557505050565b61036e93945061287661287a9392611a4292016126f1612866825192515190565b6128706001610de9565b90612783565b5190565b612887633b9aca00610de9565b906127c0565b91909261289861255a565b506000956128a587610de9565b861180612993575b6128b690612562565b6128c08585613ff1565b946003976128cc895490565b956128db612658612652875190565b976128e583610de9565b8881101561290c57806126958b6126908f9461268a61091882612907986108bb565b6128e5565b509193959890929496995061292084610de9565b61292b61036e895190565b81101561296057806126958c6126906129558461294f6126e68f9861295b996125d1565b9361191b565b8d6125d1565b612920565b509193969092955061298394985061036e9761297b87610de9565b9788956129c7565b9161272d61036e60208501515190565b506128b66129a16005610de9565b871090506128ad565b9061036e91602081830312156120cf576129c2600080fd5b6120cf565b929093959194956129d661255a565b506129e08761402d565b9182976129eb600090565b9586906000906129fa82610de9565b881196612a088c8c846123f9565b906080820191612a16835190565b612a226119d187610de9565b11612d50575b505050600199612a378b610de9565b871180612d16575b612a53575b50505050505050505050505090565b908291612a618c9594610de9565b945b612a6e575b50612a44565b612a7961036e885190565b851015612d11578c94612a926117b56126e6838b6125d1565b612a9b83610355565b14612d02578a8a8a8a612abb612ab46126e687846125d1565b87896123f9565b9960808b019a612ac98c5190565b612ad56119d18c610de9565b14612ced57612ae38d61402d565b94612c47575b8b6128768c8c612b419a9b9c9d9e9f94612b0f612b07612b2e975190565b928201611e11565b612b276060612b2060208501611e11565b9301611e11565b928b6140c3565b612b3b6126e689856125d1565b906129c7565b8d612b57612b516117b58461427b565b91610355565b1480612c27575b612b75575b506001015b9a5b9a939291908b612a63565b9a8b919e91608081018c612b87825190565b916080860192612b9b6119d161036e865190565b11612bc4575b505050612b689250612bbc9150805160409091015151015190565b9a9d90612b63565b84612c01612bf261287a6119d195612bec612c0698612870612be761036e995190565b915190565b906118f5565b95805160409091015151015190565b612783565b11612c14578b818c81612ba1565b9a509c612c219060010190565b9a612b6a565b508b612c416119d16118fc84805160409091015151015190565b11612b5e565b899b8a9b5061287682612c886020612c70612b419c9d9e9f61217761217791612b2e9901611e11565b6369cff80d90612c7f60405190565b93849260e01b90565b825260049082905afa908115612ce0575b600091612cb2575b509d509250509b9998979650612ae9565b612cd3915060203d8111612cd9575b612ccb81836105f6565b8101906129aa565b38612ca1565b503d612cc1565b612ce861213b565b612c99565b505050505050612c2191929394955060010190565b612c2191929394955060010190565b612a68565b50612d30612d2660208701515190565b6128876020610de9565b612d496119d161036e612d436002610de9565b8b612783565b1115612a3f565b9091929a5088612da0575b84839261287692612d6d612d97965190565b612d78888301611e11565b90612d916060612d8a60208601611e11565b9401611e11565b936140c3565b97388080612a28565b612d979291945080612dc16020612c70612177612177896128769701611e11565b825260049082905afa908115612e04575b600091612de6575b50959293509050612d5b565b612dfe915060203d8111612cd957612ccb81836105f6565b38612dda565b612e0c61213b565b612dd2565b90612e1e92913390612f91565b50565b3561036e81610470565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe13682900301821215612e8f575b01602081359167ffffffffffffffff8311612e82575b0191602082023603831361034257565b612e8a600080fd5b612e72565b612e97600080fd5b612e5c565b3561036e816104db565b6001907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612261570190565b61039190610de9565b9095949261034a94612f15610a8c92612f0b608096612f0160a088019c6000890152565b6020870190612ed4565b6040850190610388565b6060830190610388565b15612f2657565b60405162461bcd60e51b815260206004820152602560248201527f59616b526f757465723a20496e73756666696369656e74206f7574707574206160448201527f6d6f756e740000000000000000000000000000000000000000000000000000006064820152608490fd5b92939183916131079161303c90612fa785612e21565b90612fb26000610de9565b811180156134c9575b61347a575b506020612feb612177612177612fe6612fdc60408b018b612e2b565b6122db6000610de9565b612e9c565b612ffe612fe6612fdc60808a018a612e2b565b9061300860405190565b948592839182917f70a08231000000000000000000000000000000000000000000000000000000005b835260048301610395565b03915afa91821561346d575b60009261344b575b508192613085925061306b612fe6612fdc6040890189612e2b565b9061307f612fe6612fdc60808a018a612e2b565b91613573565b6130ed60206130a3612177612177612fe6612fdc60408a018a612e2b565b6130b6612fe6612fdc6080890189612e2b565b906130c060405190565b938492839182917f70a0823100000000000000000000000000000000000000000000000000000000613031565b03915afa908115613321575b600091613303575b50612783565b93613133612fe661311b6040850185612e2b565b6122db61286661312e6040890189612e2b565b905090565b9261313e6000610de9565b955b606084019061315561036e61312e8488612e2b565b8810156133c25790879161317261036e61286661312e858a612e2b565b8310156133ba578561319a612fe661318d6080840184612e2b565b6122db6126526001610de9565b915b6131c8612177612177612fe66131b56040870187612e2b565b6122db6131c26001610de9565b8c61191b565b9360206131d460405190565b9586907f70a0823100000000000000000000000000000000000000000000000000000000825281806132098960048301610395565b03915afa9485156133ad575b60009561336e575b50926132ef612177612177612fe6896122db6132a3896000806132fd9f9b6132f79f9e8f6130ed9f60209f8f93613270612177612177612fe68561326a6132d4968d996132c99b50612e2b565b90612269565b94896132b0612fe663eab90da6956122db6132a3613298612fe68461326a60408a018a612e2b565b956040810190612e2b565b919092611a506001610de9565b90873b15613361575b6040519a8b998a98899760e01b90565b875260048701612edd565b03925af18015613354575b61332e575b506040810190612e2b565b6040516130c0565b96612ea6565b95613140565b61331b915060203d8111612cd957612ccb81836105f6565b38613101565b61332961213b565b6130f9565b6133479060005b61333f81836105f6565b810190610337565b386132e4565b503d613335565b61335c61213b565b6132df565b613369600080fd5b6132b9565b839550868593949592819260203d81116133a6575b61338d81836105f6565b8101613398916129aa565b97509250509392919361321d565b503d613383565b6133b561213b565b613215565b85859161319c565b9594936133fd9297506134039350612fe69150612fdc906133f36133eb61036e60208401612e21565b891015612f1f565b6040810190612e2b565b92612e21565b91836134386134327f9fc8352e52998db4087d5e6e1c1aafa38788e749e5d7a24f5cb230f73795440293611544565b93611544565b93613445611fe460405190565b0390a390565b61308592506134679060203d8111612cd957612ccb81836105f6565b91613050565b61347561213b565b613048565b61348d915061348888612e21565b613533565b6134c3816134a4612fe6612fdc60408a018a612e2b565b90856134bd6134b3600261201e565b92612c018d612e21565b92613573565b38612fc0565b506134d46001611592565b6134e16119d16000610de9565b11612fbb565b156134ee57565b60405162461bcd60e51b815260206004820152601b60248201527f59616b526f757465723a20496e73756666696369656e742066656500000000006044820152606490fd5b9061356e61036e92613543600090565b5061355c61355461036e6001611592565b8410156134e7565b612bec613567611259565b9384612783565b6127c0565b9291906135826117b530611544565b61358b82610355565b146135a15761359c61034a94611544565b613cf8565b506135ae61034a93611544565b613c90565b156135ba57565b60405162461bcd60e51b815260206004820152602860248201527f59616b526f757465723a2050617468206e6565647320746f20626567696e207760448201527f69746820574554480000000000000000000000000000000000000000000000006064820152608490fd5b90612e1e929161369361368e612fe66136876136556136476040870187612e2b565b93906000946122db86610de9565b613681612b517f00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b557610355565b146135b3565b8301612e21565b6136a2565b61369c30611544565b90612f91565b60006136ee6136d36121777f00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b557611544565b63d0e30db0813b15613725575b604051948593849260e01b90565b825281600481015b03925af18015613718575b6137085750565b61034a90600061333f81836105f6565b61372061213b565b613701565b61372d600080fd5b6136e0565b1561373957565b60405162461bcd60e51b815260206004820152602660248201527f59616b526f757465723a2050617468206e6565647320746f20656e642077697460448201527f68205745544800000000000000000000000000000000000000000000000000006064820152608490fd5b6138189061034a93926138086137d6612fe66040850161312e6122db6128666137cd848a612e2b565b9390948a612e2b565b613802612b517f00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b557610355565b14613732565b3361381230611544565b92612f91565b6138218161382e565b613829610dad565b61389c565b60006136f6916138606121777f00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b557611544565b61388183632e1a7d4d833b1561388f575b6040519687958694859360e01b90565b835260048301526024820190565b613897600080fd5b613871565b916138a630611544565b6138b2612b5183610355565b036138bc57505050565b6138c76117b5610dad565b6138d084610355565b0361390a57600080935080926138e96121778394611544565b828215613901575bf1156138f957565b61034a61213b565b506108fc6138f1565b6135ae61034a93611544565b949290979695939160e08601986000870161393091610388565b6020860161393d91610388565b6040850152606084015260ff16608083015260a082015260c00152565b929561034a96612fe693966139cc6139d787959861397b6040880188612e2b565b92909661399761217761217760009c8d9b8c986122db8a610de9565b9563d505accf9333986139b4876139ad30611544565b9d01612e21565b893b15613a18575b6040519c8d9b8c9a8b9960e01b90565b895260048901613916565b03925af18015613a0b575b6139ee575b5050612e11565b81613a0492903d1061334d5761333f81836105f6565b38806139e7565b613a1361213b565b6139e2565b613a20600080fd5b6139bc565b929561034a96612fe693966139cc613a4687959861397b6040880188612e2b565b03925af18015613a7a575b613a5d575b50506137a4565b81613a7392903d1061334d5761333f81836105f6565b3880613a56565b613a8261213b565b613a51565b61034a907f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab956115db565b61034a907f339759585899103d2ace64958e37e18ccb0504652c81d4a1b8aa80fe2126ab95611728565b61034a903361058b565b61034a903390613afd613af6610df6565b91826115db565b6117a4565b61034a9190613b13611c9533611c6f565b613b64565b15613b1f57565b60405162461bcd60e51b815260206004820152601260248201527f4e6f7468696e6720746f207265636f76657200000000000000000000000000006044820152606490fd5b613b79613b716000610de9565b835b11613b18565b613b8d82613b8683611544565b3390613c90565b613bc4613bba7f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa2892611544565b926104c160405190565b0390a2565b9061034a91613b02565b61034a90613be3611c9533611c6f565b613b8d6000613bfa613bf482610de9565b84613b73565b8080808086613c0b61217733611544565b828215613c25575bf1610da457613c2061213b565b610da4565b506108fc613c13565b61034a90613bd3565b613c50613c4a61036e9263ffffffff1690565b60e01b90565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b91602061034a929493611f6460408201966000830190610388565b613cd3600492613cc461034a95613caa63a9059cbb613c37565b92613cb460405190565b9687946020860190815201613c75565b602082018103825203836105f6565b613f90565b604090611f6461034a949695939661213160608401986000850190610388565b90613cd390613cc461034a95600495613d146323b872dd613c37565b93613d1e60405190565b9788956020870190815201613cd8565b15613d3557565b60405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608490fd5b613cd3600492613cc461034a95613dcd600084613dbc82610de9565b8414918215613dda575b5050613d2e565b613caa63095ea7b3613c37565b9091506020613de889611544565b63dd62ed3e90613e14613dfa30611544565b92613e1f613e0760405190565b9788958694859460e01b90565b845260048401612028565b03915afa918215613e70575b600092613e48575b506119d1613e4091610de9565b148438613dc6565b613e40919250613e686119d19160203d8111612cd957612ccb81836105f6565b929150613e33565b613e7861213b565b613e2b565b3d15613e9757613e8c3d610e7b565b903d6000602084013e565b606090565b15613ea357565b60405162461bcd60e51b815280611709600482016020808252818101527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604082015260600190565b801515610403565b9050519061034a82613eec565b9061036e9160208183031215613ef457613f19600080fd5b613ef4565b15613f2557565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608490fd5b600091613f9d8392611544565b9082602082019151925af1613fb9613fb3613e7d565b91613e9c565b8051613fc86119d16000610de9565b11613fd05750565b613fec816020613fe161034a945190565b818301019101613f01565b613f1e565b9190604061401261400061255a565b9261400b8496614017565b8452614017565b910152565b90602091614027611a5684610de9565b92830152565b61403561255a565b5061036e6000820151916123a5602082015191614082604082015161407b6140636080606086015195015190565b9561407461406f612211565b998a52565b6020890152565b6040870152565b6060850152565b6116529061036e93926115f9565b6140b7929161034a916140a960405190565b948592602084019283614089565b908103825203836105f6565b90926103919360809361034a97966140ea60408601916140e4835191614017565b90614097565b90526140ff60208501916140e4835191614017565b905261411460008401916140e4835191614017565b905261412960608301916140e4835191614017565b90520191614135835190565b61191b565b61414261255a565b5061036e6141536000830151614219565b916123a56141646020830151614190565b916140826141756040830151614190565b61407b614063608061418a6060870151614190565b95015190565b908151916141a661265860209461288786610de9565b92836141b26000610de9565b6141c961036e6141c0865190565b61288786610de9565b8110156142125761420d906142086141fe6141f86141ef6141e988610de9565b856118f5565b611a5088610de9565b87015190565b612690838a6125d1565b612ea6565b6141b2565b5093505050565b9081519161422f61265860209461288786610de9565b928361423b6000610de9565b61424961036e6141c0865190565b81101561421257614276906142086142696141f86141ef6141e988610de9565b614273838a6125d1565b52565b61423b565b604061036e91614289600090565b500151805101519056fea26469706673582212209bab7ef2e02c88142d1a19cfb4bd54703a6e2d7623fefdd4d93a123ad69be2eb64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000001bb7b44cc398aaa2b76ac6253f0f5634279db9d00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b5570000000000000000000000000000000000000000000000000000000000000003000000000000000000000000f05902d8eb53a354c9ddc67175df3d9bee1f95810000000000000000000000009cc2b9f9a6194c5cc827c88571e42ceaa76fdf4700000000000000000000000036049d5b4aaef6c39cd4a5bd1a2e1224f07621a20000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cf800f4948d16f23333508191b1b1591daf70438000000000000000000000000a2235d059f80e176d931ef76b6c51953eb3fbef400000000000000000000000048b62137edfa95a428d35c09e44256a739f6b557
-----Decoded View---------------
Arg [0] : _adapters (address[]): 0xF05902D8EB53a354c9dDC67175df3D9BEe1F9581,0x9CC2B9F9a6194C5CC827C88571E42cEAA76FDF47,0x36049d5B4aAef6c39Cd4a5bD1A2E1224F07621a2
Arg [1] : _trustedTokens (address[]): 0xcF800F4948D16F23333508191B1B1591daF70438,0xA2235d059F80e176D931Ef76b6C51953Eb3fBEf4,0x48b62137EdfA95a428D35C09E44256a739F6B557
Arg [2] : _feeClaimer (address): 0x01Bb7B44cc398AaA2b76Ac6253F0F5634279Db9D
Arg [3] : _wrapped_native (address): 0x48b62137EdfA95a428D35C09E44256a739F6B557
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 00000000000000000000000001bb7b44cc398aaa2b76ac6253f0f5634279db9d
Arg [3] : 00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b557
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [5] : 000000000000000000000000f05902d8eb53a354c9ddc67175df3d9bee1f9581
Arg [6] : 0000000000000000000000009cc2b9f9a6194c5cc827c88571e42ceaa76fdf47
Arg [7] : 00000000000000000000000036049d5b4aaef6c39cd4a5bd1a2e1224f07621a2
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [9] : 000000000000000000000000cf800f4948d16f23333508191b1b1591daf70438
Arg [10] : 000000000000000000000000a2235d059f80e176d931ef76b6c51953eb3fbef4
Arg [11] : 00000000000000000000000048b62137edfa95a428d35c09e44256a739f6b557
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
APE | Ape (APE) | 100.00% | $1.16 | 0.00081368 | $0.000947 |
[ 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.