Source Code
Latest 25 from a total of 736 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Unzap From Matri... | 132830485 | 410 days ago | IN | 0 ETH | 0.000001100913 | ||||
| Unzap From Matri... | 132097544 | 427 days ago | IN | 0 ETH | 0.000002254647 | ||||
| Unzap From Matri... | 132097528 | 427 days ago | IN | 0 ETH | 0.000001229537 | ||||
| Unzap From Matri... | 131155276 | 449 days ago | IN | 0 ETH | 0.000000616894 | ||||
| Unzap From Matri... | 129227113 | 494 days ago | IN | 0 ETH | 0.000002605872 | ||||
| Unzap From Matri... | 128345348 | 514 days ago | IN | 0 ETH | 0.000003855717 | ||||
| Unzap From Matri... | 128333709 | 515 days ago | IN | 0 ETH | 0.000000130627 | ||||
| Unzap From Matri... | 128300367 | 515 days ago | IN | 0 ETH | 0.000002032657 | ||||
| Unzap From Matri... | 127965230 | 523 days ago | IN | 0 ETH | 0.000002543538 | ||||
| Unzap From Matri... | 127844613 | 526 days ago | IN | 0 ETH | 0.000003347776 | ||||
| Unzap From Matri... | 127821880 | 526 days ago | IN | 0 ETH | 0.000001970365 | ||||
| Unzap From Matri... | 127773470 | 528 days ago | IN | 0 ETH | 0.000001305157 | ||||
| Unzap From Matri... | 127350633 | 537 days ago | IN | 0 ETH | 0.000001536959 | ||||
| Unzap From Matri... | 127132148 | 542 days ago | IN | 0 ETH | 0.000000452964 | ||||
| Unzap From Matri... | 127132138 | 542 days ago | IN | 0 ETH | 0.000000334151 | ||||
| Unzap From Matri... | 127132129 | 542 days ago | IN | 0 ETH | 0.000000401411 | ||||
| Unzap From Matri... | 127130927 | 542 days ago | IN | 0 ETH | 0.000000086643 | ||||
| Unzap From Matri... | 127130921 | 542 days ago | IN | 0 ETH | 0.000000073045 | ||||
| Unzap From Matri... | 127130915 | 542 days ago | IN | 0 ETH | 0.000000270369 | ||||
| Unzap From Matri... | 127130906 | 542 days ago | IN | 0 ETH | 0.00000068005 | ||||
| Unzap From Matri... | 127130893 | 542 days ago | IN | 0 ETH | 0.000001058487 | ||||
| Unzap From Matri... | 127130886 | 542 days ago | IN | 0 ETH | 0.000000546213 | ||||
| Unzap From Matri... | 127130877 | 542 days ago | IN | 0 ETH | 0.000000526312 | ||||
| Unzap From Matri... | 127130863 | 542 days ago | IN | 0 ETH | 0.000000248307 | ||||
| Unzap From Matri... | 127130851 | 542 days ago | IN | 0 ETH | 0.000000102489 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 132097544 | 427 days ago | 0.000003579674651 ETH | ||||
| 132097544 | 427 days ago | 0.000003579674651 ETH | ||||
| 132097528 | 427 days ago | 0.000022302371898 ETH | ||||
| 132097528 | 427 days ago | 0.000022302371898 ETH | ||||
| 131155276 | 449 days ago | 0.007704566730632 ETH | ||||
| 131155276 | 449 days ago | 0.007704566730632 ETH | ||||
| 128345348 | 514 days ago | 1.146683419264545 ETH | ||||
| 128345348 | 514 days ago | 1.146683419264545 ETH | ||||
| 128333709 | 515 days ago | 0.000011091803293 ETH | ||||
| 128333709 | 515 days ago | 0.000011091803293 ETH | ||||
| 128300367 | 515 days ago | 0.070868566118852 ETH | ||||
| 128300367 | 515 days ago | 0.070868566118852 ETH | ||||
| 127965230 | 523 days ago | 0.078391437366438 ETH | ||||
| 127965230 | 523 days ago | 0.078391437366438 ETH | ||||
| 127821880 | 526 days ago | 0.196938128968322 ETH | ||||
| 127821880 | 526 days ago | 0.196938128968322 ETH | ||||
| 127350633 | 537 days ago | 0.001131314993445 ETH | ||||
| 127350633 | 537 days ago | 0.001131314993445 ETH | ||||
| 127132148 | 542 days ago | 0.007304310670711 ETH | ||||
| 127132148 | 542 days ago | 0.007304310670711 ETH | ||||
| 127132138 | 542 days ago | 0.00112161702217 ETH | ||||
| 127132138 | 542 days ago | 0.00112161702217 ETH | ||||
| 127132129 | 542 days ago | 0.001013071062281 ETH | ||||
| 127132129 | 542 days ago | 0.001013071062281 ETH | ||||
| 127130921 | 542 days ago | 0.004850182926285 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ZapperOptimismV3
Compiler Version
v0.8.14+commit.80d49f37
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
import './interfaces/IUniswapV2Pair.sol';
import './interfaces/ISolidlyRouter.sol';
import './interfaces/IWETH.sol';
import './interfaces/EqualizerGauge.sol';
import './interfaces/IMatrixVault.sol';
import './strategies/MatrixSwapHelperV2.sol';
import './interfaces/IVoter.sol';
contract ZapperOptimismV3 is MatrixSwapHelperV2, Ownable {
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.AddressSet;
event DefaultRouterChanged(address indexed _oldRouter, address indexed _newRouter);
event CustomRouterSet(address indexed _lpToken, address indexed _customRouter);
event ZapIn(address indexed _user, address indexed _vault, address indexed _want, uint256 _amountIn);
event ZapOut(address indexed _user, address indexed _vault, address indexed _want, uint256 _amountOut);
string public constant VERSION = '3';
address public constant WETH = 0x4200000000000000000000000000000000000006;
address public constant USDC = 0x7F5c764cBc14f9669B88837ca1490cCa17c31607;
address internal constant VELO_ROUTER = 0xa062aE8A9c5e11aaA026fc2670B0D65cCc8B2858;
address internal constant OPX = 0xc38464250F51123078BBd7eA574E185F6623d037;
address internal constant VELO = 0x9560e827aF36c94D2Ac33a39bCE1Fe78631088Db;
/// @dev Mapping of LP ERC20 -> Router
/// In order to support a wider range of UniV2 forks
mapping(address => address) public customRouter;
mapping(address => MatrixSwapHelperV2.RouterType) public routerToType;
/// @dev Mapping of Factory -> Router to retrieve
/// the default router for LP token
mapping(address => address) public factoryToRouter;
/// @notice SushiSwap ROUTER AS DEFAULT FOR LP TOKENS AND SWAPS
constructor() MatrixSwapHelperV2(VELO_ROUTER) {
// Velodrome
factoryToRouter[0xF1046053aa5682b4F9a81b5481394DA16BE5FF5a] = VELO_ROUTER;
routerToType[VELO_ROUTER] = MatrixSwapHelperV2.RouterType.SolidlyV2;
routers.push(VELO_ROUTER);
whitelistedAddresses.add(VELO);
whitelistedAddresses.add(OPX);
whitelistedAddresses.add(VELO_ROUTER);
// setting OPX
address[] memory _wethOpx = new address[](3);
_wethOpx[0] = WETH;
_wethOpx[1] = VELO;
_wethOpx[2] = OPX;
_setSwapPath(WETH, OPX, VELO_ROUTER, _wethOpx);
address[] memory _opxWeth = new address[](3);
_opxWeth[0] = OPX;
_opxWeth[1] = VELO;
_opxWeth[2] = WETH;
_setSwapPath(OPX, WETH, VELO_ROUTER, _opxWeth);
}
receive() external payable {}
/// @notice Get swap custom swap paths, if any
/// @dev Otherwise reverts to default FROMTOKEN-WETH-TOTOKEN behavior
function getSwapPath(
address _fromToken,
address _toToken,
address _unirouter
) public view override returns (SwapPath memory _swapUniV2Path) {
bytes32 _swapUniV2Key = keccak256(abi.encodePacked(_fromToken, _toToken, _unirouter));
if (swapPaths[_swapUniV2Key].path.length == 0) {
if (_fromToken != WETH && _toToken != WETH) {
address[] memory _path = new address[](3);
_path[0] = _fromToken;
_path[1] = WETH;
_path[2] = _toToken;
_swapUniV2Path.path = _path;
} else {
address[] memory _path = new address[](2);
_path[0] = _fromToken;
_path[1] = _toToken;
_swapUniV2Path.path = _path;
}
_swapUniV2Path.unirouter = _unirouter;
} else {
return swapPaths[_swapUniV2Key];
}
}
/// @dev Allows owner to set a custom swap path from a token to another
/// @param _unirouter Can also set a custom unirouter for the swap, or address(0) for default router (spooky)
function setSwapPath(
address _fromToken,
address _toToken,
address _unirouter,
address[] memory _path
) external onlyOwner {
_setSwapPath(_fromToken, _toToken, _unirouter, _path);
}
function zapToLp(
address _fromToken,
address _toLpToken,
uint256 _amountIn,
uint256 _minLpAmountOut
) external payable returns (uint256 _lpAmountOut) {
_lpAmountOut = _zapToLp(_fromToken, _toLpToken, _amountIn, _minLpAmountOut);
IERC20(_toLpToken).safeTransfer(msg.sender, _lpAmountOut);
}
function zapToMatrix(
address _fromToken,
address _matrixVault,
uint256 _amountIn,
uint256 _minLpAmountOut
) external payable returns (uint256 _lpAmountOut) {
IMatrixVault _vault = IMatrixVault(_matrixVault);
address _toLpToken = _vault.want();
address _token0 = IUniswapV2Pair(_toLpToken).token0();
address _token1 = IUniswapV2Pair(_toLpToken).token1();
// check balances to return leftovers
uint256 _token0BalanceBefore = IERC20(_token0).balanceOf(address(this));
uint256 _token1BalanceBefore = IERC20(_token1).balanceOf(address(this));
_lpAmountOut = _zapToLp(_fromToken, _toLpToken, _amountIn, _minLpAmountOut);
uint256 _vaultBalanceBefore = _vault.balanceOf(address(this));
IERC20(_toLpToken).safeApprove(_matrixVault, _lpAmountOut);
_vault.deposit(_lpAmountOut);
uint256 _vaultAmountOut = _vault.balanceOf(address(this)) - _vaultBalanceBefore;
require(_vaultAmountOut > 0, 'deposit-in-vault-failed');
_vault.transfer(msg.sender, _vaultAmountOut);
emit ZapIn(msg.sender, address(_vault), _toLpToken, _lpAmountOut);
// returning leftovers
uint256 _token0BalanceAfter = IERC20(_token0).balanceOf(address(this));
uint256 _token1BalanceAfter = IERC20(_token1).balanceOf(address(this));
if ((_token0BalanceAfter - _token0BalanceBefore) > 0) {
IERC20(_token0).safeTransfer(msg.sender, (_token0BalanceAfter - _token0BalanceBefore));
}
if ((_token1BalanceAfter - _token1BalanceBefore) > 0) {
IERC20(_token1).safeTransfer(msg.sender, (_token1BalanceAfter - _token1BalanceBefore));
}
}
function unzapFromMatrix(
address _matrixVault,
address _toToken,
uint256 _withdrawAmount,
uint256 _minAmountOut
) external returns (uint256 _amountOut) {
IMatrixVault _vault = IMatrixVault(_matrixVault);
address _fromLpToken = _vault.want();
_vault.transferFrom(msg.sender, address(this), _withdrawAmount);
_vault.withdraw(_withdrawAmount);
_amountOut = _unzapFromLp(_fromLpToken, _toToken, IERC20(_fromLpToken).balanceOf(address(this)), _minAmountOut);
emit ZapOut(msg.sender, address(_vault), _fromLpToken, _amountOut);
}
function unzapFromLp(
address _fromLpToken,
address _toToken,
uint256 _amountLpIn,
uint256 _minAmountOut
) external returns (uint256 _amountOut) {
IERC20(_fromLpToken).safeTransferFrom(msg.sender, address(this), _amountLpIn);
_amountOut = _unzapFromLp(_fromLpToken, _toToken, _amountLpIn, _minAmountOut);
}
/// @notice In case tokens got stuck/mistakenly sent here
function sweepERC20(address _token) external onlyOwner {
IERC20(_token).safeTransfer(msg.sender, IERC20(_token).balanceOf(_token));
}
function addRouter(address _factory, address _router) external onlyOwner {
require(factoryToRouter[_factory] == address(0), 'already-set');
factoryToRouter[_factory] = _router;
}
function setCustomRouter(address lpToken, address router) external onlyOwner {
// check if in whitelist
for (uint256 i = 0; i < routers.length; i++) {
if (routers[i] == router) {
break;
}
if (i == routers.length - 1) {
revert('router-not-whitelisted');
}
}
customRouter[lpToken] = router;
}
/// @notice Get router for LPToken
function _getRouter(address _lpToken) internal view virtual returns (address) {
if (customRouter[_lpToken] != address(0)) return customRouter[_lpToken];
address _factory = IUniswapV2Pair(_lpToken).factory();
require(factoryToRouter[_factory] != address(0), 'unsupported-router');
return factoryToRouter[_factory];
}
function getBestSwapPath(
address fromToken,
address toToken,
uint256 amount
) public view returns (SwapPath memory _bestSwapPath) {
address[] memory _routers = routers;
uint256 _bestAmount = 0;
for (uint256 i = 0; i < _routers.length; i++) {
address _router = _routers[i];
SwapPath memory _swapPath = getSwapPath(fromToken, toToken, _router);
MatrixSwapHelperV2.RouterType _routerType = routerToType[_router];
uint256 amountOut = _estimateSwap(_swapPath, amount, _routerType);
if (amountOut > _bestAmount) {
_bestAmount = amountOut;
_bestSwapPath = _swapPath;
}
// testing direct path if weth is not present
if (fromToken != WETH && toToken != WETH) {
SwapPath memory _swapPathDirect;
address[] memory _path = new address[](2);
_path[0] = fromToken;
_path[1] = toToken;
_swapPathDirect.path = _path;
_swapPathDirect.unirouter = _router;
uint256 amountOutDirect = _estimateSwap(_swapPathDirect, amount, _routerType);
if (amountOutDirect > _bestAmount) {
_bestAmount = amountOutDirect;
_bestSwapPath = _swapPathDirect;
}
}
// testing usdc path if usdc is not present
if (fromToken != USDC && toToken != USDC) {
SwapPath memory _swapPathUSDC;
address[] memory _path = new address[](3);
_path[0] = fromToken;
_path[1] = USDC;
_path[2] = toToken;
_swapPathUSDC.path = _path;
_swapPathUSDC.unirouter = _router;
uint256 amountOutUSDC = _estimateSwap(_swapPathUSDC, amount, _routerType);
if (amountOutUSDC > _bestAmount) {
_bestAmount = amountOutUSDC;
_bestSwapPath = _swapPathUSDC;
}
}
}
require(_bestAmount > 0, 'no-path');
return _bestSwapPath;
}
function _zapToLp(
address _fromToken,
address _toLpToken,
uint256 _amountIn,
uint256 _minLpAmountOut
) internal virtual returns (uint256 _lpAmountOut) {
if (msg.value > 0) {
// If you send FTM instead of WETH these requirements must hold.
require(_fromToken == WETH, 'invalid-from-token');
require(_amountIn == msg.value, 'invalid-amount-in');
// Auto-wrap FTM to WETH
IWETH(WETH).deposit{ value: msg.value }();
} else {
IERC20(_fromToken).safeTransferFrom(msg.sender, address(this), _amountIn);
}
address _router = _getRouter(_toLpToken);
address _token0 = IUniswapV2Pair(_toLpToken).token0();
address _token1 = IUniswapV2Pair(_toLpToken).token1();
// Uses lpToken' _router as the default router
// You can override this by using setting a custom path
// Using setSwapPath
SwapPath memory swapPathToken0 = getBestSwapPath(_fromToken, _token0, _amountIn / 2);
SwapPath memory swapPathToken1 = getBestSwapPath(_fromToken, _token1, _amountIn - (_amountIn / 2));
uint256 _token0Out;
uint256 _token1Out;
bool _isStable = false;
if (routerToType[_router] == MatrixSwapHelperV2.RouterType.Solidly || routerToType[_router] == MatrixSwapHelperV2.RouterType.SolidlyV2) {
_isStable = IUniswapV2Pair(_toLpToken).stable();
}
if (!_isStable) {
_token0Out = _swap(swapPathToken0, _amountIn / 2, routerToType[swapPathToken0.unirouter]);
_token1Out = _swap(swapPathToken1, _amountIn - (_amountIn / 2), routerToType[swapPathToken1.unirouter]);
} else {
uint256 out0 = _amountIn / 2;
uint256 out1 = _amountIn - out0;
// quote add liquidity
out0 = _token0 != _fromToken ? (_estimateSwap(swapPathToken0, out0, routerToType[swapPathToken0.unirouter]) * 1e18) / 10**IERC20Metadata(_token0).decimals() : out0;
out1 = _token1 != _fromToken ? (_estimateSwap(swapPathToken1, out1, routerToType[swapPathToken1.unirouter]) * 1e18) / 10**IERC20Metadata(_token1).decimals() : out1;
(uint256 amountA, uint256 amountB, ) = _quoteAddLiquidity(routerToType[_router], _token0, _token1, true, _router, _toLpToken, out0, out1);
amountA = (amountA * 1e18) / 10**IERC20Metadata(_token0).decimals();
amountB = (amountB * 1e18) / 10**IERC20Metadata(_token1).decimals();
// calculating ratio
uint256 ratio = (((out0 * 1e18) / out1) * amountB) / amountA;
// calculating amounts
uint256 _amount0In = (_amountIn * 1e18) / (ratio + 1e18);
uint256 _amount1In = _amountIn - _amount0In;
// swapping
_token0Out = _swap(swapPathToken0, _amount0In, routerToType[swapPathToken0.unirouter]);
_token1Out = _swap(swapPathToken1, _amount1In, routerToType[swapPathToken1.unirouter]);
}
IERC20(_token0).safeApprove(_router, 0);
IERC20(_token1).safeApprove(_router, 0);
IERC20(_token0).safeApprove(_router, _token0Out);
IERC20(_token1).safeApprove(_router, _token1Out);
uint256 _lpBalanceBefore = IERC20(_toLpToken).balanceOf(address(this));
_addLiquidity(_router, _token0, _token1, _token0Out, _token1Out, _isStable);
_lpAmountOut = IERC20(_toLpToken).balanceOf(address(this)) - _lpBalanceBefore;
require(_lpAmountOut >= _minLpAmountOut, 'slippage-rekt-you');
}
function _addLiquidity(
address _router,
address _token0,
address _token1,
uint256 _token0Out,
uint256 _token1Out,
bool _stable
) internal virtual {
MatrixSwapHelperV2.RouterType _routerType = routerToType[_router];
if (_routerType == MatrixSwapHelperV2.RouterType.UniV2) {
IUniswapV2Router02(_router).addLiquidity(_token0, _token1, _token0Out, _token1Out, 0, 0, address(this), block.timestamp);
} else if (_routerType == MatrixSwapHelperV2.RouterType.Solidly || _routerType == MatrixSwapHelperV2.RouterType.SolidlyV2) {
(uint256 amountA, uint256 amountB, uint256 liquidity) = ISolidlyRouter(_router).addLiquidity(
_token0,
_token1,
_stable,
_token0Out,
_token1Out,
0,
0,
address(this),
block.timestamp
);
} else {
revert('invalid-router-type');
}
}
function _removeLiquidity(
address _router,
address _token0,
address _token1,
uint256 _amountLpIn,
bool _stable
) internal virtual {
MatrixSwapHelperV2.RouterType _routerType = routerToType[_router];
if (_routerType == MatrixSwapHelperV2.RouterType.UniV2) {
IUniswapV2Router02(_router).removeLiquidity(_token0, _token1, _amountLpIn, 0, 0, address(this), block.timestamp);
} else if (_routerType == MatrixSwapHelperV2.RouterType.Solidly || _routerType == MatrixSwapHelperV2.RouterType.SolidlyV2) {
ISolidlyRouter(_router).removeLiquidity(_token0, _token1, _stable, _amountLpIn, 0, 0, address(this), block.timestamp);
} else {
revert('invalid-router-type');
}
}
function _unzapFromLp(
address _fromLpToken,
address _toToken,
uint256 _amountLpIn,
uint256 _minAmountOut
) internal virtual returns (uint256 _amountOut) {
address _router = _getRouter(_fromLpToken);
address _token0 = IUniswapV2Pair(_fromLpToken).token0();
address _token1 = IUniswapV2Pair(_fromLpToken).token1();
IERC20(_fromLpToken).safeApprove(_router, 0);
IERC20(_fromLpToken).safeApprove(_router, _amountLpIn);
bool _isStable = false;
if (routerToType[_router] == MatrixSwapHelperV2.RouterType.Solidly || routerToType[_router] == MatrixSwapHelperV2.RouterType.SolidlyV2) {
_isStable = IUniswapV2Pair(_fromLpToken).stable();
}
_removeLiquidity(_router, _token0, _token1, _amountLpIn, _isStable);
// Uses lpToken' _router as the default router
// You can override this by using setting a custom path
// Using setSwapPath
SwapPath memory swapPathToken0 = getBestSwapPath(_token0, _toToken, IERC20(_token0).balanceOf(address(this)));
SwapPath memory swapPathToken1 = getBestSwapPath(_token1, _toToken, IERC20(_token1).balanceOf(address(this)));
MatrixSwapHelperV2.RouterType path0RouterType = routerToType[swapPathToken0.unirouter];
MatrixSwapHelperV2.RouterType path1RouterType = routerToType[swapPathToken1.unirouter];
_swap(swapPathToken0, IERC20(_token0).balanceOf(address(this)), path0RouterType);
_swap(swapPathToken1, IERC20(_token1).balanceOf(address(this)), path1RouterType);
_amountOut = IERC20(_toToken).balanceOf(address(this));
require(_amountOut >= _minAmountOut, 'slippage-rekt-you');
if (_toToken == WETH) {
IWETH(WETH).withdraw(_amountOut);
(bool _success, ) = msg.sender.call{ value: _amountOut }('');
require(_success, 'ftm-transfer-failed');
} else {
IERC20(_toToken).transfer(msg.sender, _amountOut);
}
}
function _checkPath(address[] memory _path) internal override {}
function _checkRouter(address _router) internal override {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
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));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
return _values(set._inner);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}pragma solidity >=0.5.0;
interface IUniswapV2Factory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}pragma solidity >=0.6.2;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}pragma solidity >=0.6.2;
import './IUniswapV2Router01.sol';
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
interface EqualizerGauge {
function deposit(uint256 _amount, address _recipient) external;
function deposit(uint256 _amount) external;
function withdraw(uint256 _amount) external;
function getReward(address _account) external;
function getReward(address _account, address[] memory _tokens) external;
function earned(address _account) external view returns (uint256);
function balanceOf(address _from) external view returns (uint256);
function ve() external view returns (address);
}pragma solidity >=0.6.2;
interface ICamelotRouter {
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
address referrer,
uint256 deadline
) external payable;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.14;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
interface IMatrixVault is IERC20 {
function want() external view returns (address);
function deposit(uint256) external;
function withdraw(uint256 _shares) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
interface ISolidlyRouter {
struct route {
address from;
address to;
bool stable;
}
function defaultFactory() external view returns (address);
function getAmountOut(
uint256 amountIn,
address tokenIn,
address tokenOut
) external view returns (uint256 amount, bool stable);
function getAmountsOut(uint256 amountIn, route[] memory routes) external view returns (uint256[] memory amounts);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
route[] memory routes,
address to,
uint256 deadline
) external;
function getAmountsOut(
uint256 amountIn,
route[] memory routes,
address factory
) external view returns (uint256[] memory amounts);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
route[] calldata routes,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function addLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function removeLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
function pairFor(
address tokenA,
address tokenB,
bool stable
) external view returns (address pair);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;
interface ISolidlyRouterV2 {
struct route {
address from;
address to;
bool stable;
address factory;
}
function defaultFactory() external view returns (address);
function getAmountOut(
uint256 amountIn,
address tokenIn,
address tokenOut
) external view returns (uint256 amount, bool stable);
function getAmountsOut(uint256 amountIn, route[] memory routes) external view returns (uint256[] memory amounts);
function getAmountsOut(
uint256 amountIn,
route[] memory routes,
address factory
) external view returns (uint256[] memory amounts);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
route[] calldata routes,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function quoteAddLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 amountADesired,
uint256 amountBDesired
)
external
view
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function quoteAddLiquidity(
address tokenA,
address tokenB,
bool stable,
address _factory,
uint256 amountADesired,
uint256 amountBDesired
)
external
view
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
route[] memory routes,
address to,
uint256 deadline
) external;
function addLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
)
external
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
);
function removeLiquidity(
address tokenA,
address tokenB,
bool stable,
uint256 liquidity,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
interface IUniswapV2Pair {
event Approval(address indexed owner, address indexed spender, uint256 value);
event Transfer(address indexed from, address indexed to, uint256 value);
function name() external pure returns (string memory);
function symbol() external pure returns (string memory);
function decimals() external pure returns (uint8);
function totalSupply() external view returns (uint256);
function balanceOf(address owner) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool);
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint256);
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
event Mint(address indexed sender, uint256 amount0, uint256 amount1);
event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to);
event Sync(uint112 reserve0, uint112 reserve1);
function MINIMUM_LIQUIDITY() external pure returns (uint256);
function factory() external view returns (address);
function token0() external view returns (address);
function token1() external view returns (address);
function getReserves()
external
view
returns (
uint112 reserve0,
uint112 reserve1,
uint32 blockTimestampLast
);
function price0CumulativeLast() external view returns (uint256);
function price1CumulativeLast() external view returns (uint256);
function kLast() external view returns (uint256);
function mint(address to) external returns (uint256 liquidity);
function burn(address to) external returns (uint256 amount0, uint256 amount1);
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
function skim(address to) external;
function sync() external;
function initialize(address, address) external;
function stable() external returns (bool);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;
interface IVoter {
function gauges(address) external view returns (address);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
interface IWETH is IERC20 {
function deposit() external payable;
function withdraw(uint256) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol';
import '../interfaces/IUniswapV2Pair.sol';
import '../interfaces/ISolidlyRouter.sol';
import '../interfaces/ISolidlyRouterV2.sol';
import '../interfaces/ICamelotRouter.sol';
import '@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol';
import 'hardhat/console.sol';
/// @title Swap Helper to perform swaps and setting routes in matrix zap
contract MatrixSwapHelperV2 {
using SafeERC20 for IERC20;
using EnumerableSet for EnumerableSet.AddressSet;
address[] public routers;
mapping(address => bool) public validRouter;
/// @dev Enumerable set of external tokens and routers
/// strategy can interact with
EnumerableSet.AddressSet internal whitelistedAddresses;
enum RouterType {
UniV2,
Solidly,
SolidlyV2,
Camelot
}
struct SwapPath {
RouterType routerType;
address unirouter;
address[] path;
}
mapping(bytes32 => SwapPath) internal swapPaths;
constructor(address _uniRouter) {
routers.push(_uniRouter);
validRouter[_uniRouter] = true;
}
function getWhitelistedAddresses() public virtual returns (address[] memory) {
return whitelistedAddresses.values();
}
function getSwapPath(
address _fromToken,
address _toToken,
address _unirouter
) public view virtual returns (SwapPath memory _swapPath) {
bytes32 _swapKey = keccak256(abi.encodePacked(_fromToken, _toToken, _unirouter));
require(swapPaths[_swapKey].unirouter != address(0), 'path-not-found');
return swapPaths[_swapKey];
}
function reversePath(address[] memory _path) public pure returns (address[] memory) {
uint256 length = _path.length;
address[] memory reversedPath = new address[](length);
uint256 x = 0;
for (uint256 i = length; i >= 1; i--) {
reversedPath[x] = _path[i - 1];
x++;
}
return reversedPath;
}
function _setSwapPath(
address _fromToken,
address _toToken,
address _unirouter,
address[] memory _path
) internal virtual {
require(_path[0] == _fromToken, 'invalid-path');
require(_path[_path.length - 1] == _toToken, 'invalid-path');
require(_unirouter != address(0), 'invalid-router');
_checkPath(_path);
bytes32 _swapKey = keccak256(abi.encodePacked(_fromToken, _toToken, _unirouter));
bytes32 _swapKeyReverse = keccak256(abi.encodePacked(_toToken, _fromToken, _unirouter));
address _router = _unirouter;
_checkRouter(_router);
// setting path
swapPaths[_swapKey] = SwapPath(RouterType.UniV2, _router, _path);
// setting also reverse path
swapPaths[_swapKeyReverse] = SwapPath(RouterType.UniV2, _router, reversePath(_path));
}
/// @dev Checks that tokens in path are whitelisted
/// @notice Override this to skip checks
function _checkPath(address[] memory _path) internal virtual {
for (uint256 i; i < _path.length; i++) {
require(whitelistedAddresses.contains(_path[i]), 'token-not-whitelisted');
}
}
/// @dev Checks that router for swap is whitelisted
/// @notice Override this to skip checks
function _checkRouter(address _router) internal virtual {
require(whitelistedAddresses.contains(_router), 'router-not-whitelisted');
}
function _swap(
SwapPath memory _swapPath,
uint256 _amount,
RouterType _type
) internal virtual returns (uint256 _toTokenAmount) {
address _fromToken = _swapPath.path[0];
address _toToken = _swapPath.path[_swapPath.path.length - 1];
// check for same token
if (_fromToken == _toToken) return _amount;
IERC20(_fromToken).safeApprove(_swapPath.unirouter, 0);
IERC20(_fromToken).safeApprove(_swapPath.unirouter, type(uint256).max);
uint256 _toTokenBefore = IERC20(_toToken).balanceOf(address(this));
if (_type == RouterType.UniV2) {
IUniswapV2Router02(_swapPath.unirouter).swapExactTokensForTokensSupportingFeeOnTransferTokens(_amount, 1, _swapPath.path, address(this), block.timestamp);
} else if (_type == RouterType.Camelot) {
ICamelotRouter(_swapPath.unirouter).swapExactTokensForTokensSupportingFeeOnTransferTokens(_amount, 1, _swapPath.path, address(this), address(this), block.timestamp);
} else if (_type == RouterType.Solidly) {
ISolidlyRouter(_swapPath.unirouter).swapExactTokensForTokensSupportingFeeOnTransferTokens(
_amount,
1,
_pathToSolidlyPath(_amount, _swapPath.unirouter, _swapPath.path),
address(this),
block.timestamp
);
} else if (_type == RouterType.SolidlyV2) {
ISolidlyRouterV2(_swapPath.unirouter).swapExactTokensForTokensSupportingFeeOnTransferTokens(
_amount,
1,
_pathToSolidlyV2Path(_amount, _swapPath.unirouter, _swapPath.path),
address(this),
block.timestamp
);
} else {
revert('invalid-router-type');
}
_toTokenAmount = IERC20(_toToken).balanceOf(address(this)) - _toTokenBefore;
}
function _pathToSolidlyPath(
uint256 _amount,
address _router,
address[] memory _path
) internal view returns (ISolidlyRouter.route[] memory) {
ISolidlyRouter.route[] memory _solidlyPath = new ISolidlyRouter.route[](_path.length - 1);
for (uint256 i; i < _path.length - 1; i++) {
// check max out
(uint256 amount, bool stable) = ISolidlyRouter(_router).getAmountOut(_amount, _path[i], _path[i + 1]);
_solidlyPath[i] = ISolidlyRouter.route(_path[i], _path[i + 1], stable);
_amount = amount;
}
return _solidlyPath;
}
function safeGetSolidlyV2AmountOut(
address _router,
uint256 _amount,
ISolidlyRouterV2.route[] memory _route
) internal view returns (uint256) {
try ISolidlyRouterV2(_router).getAmountsOut(_amount, _route) returns (uint256[] memory amounts) {
return amounts[amounts.length - 1];
} catch {
return 0;
}
}
function _pathToSolidlyV2Path(
uint256 _amount,
address _router,
address[] memory _path
) internal view returns (ISolidlyRouterV2.route[] memory) {
// get default factory
address factoryToUse = ISolidlyRouterV2(_router).defaultFactory();
ISolidlyRouterV2.route[] memory _solidlyPath = new ISolidlyRouterV2.route[](_path.length - 1);
for (uint256 i; i < _path.length - 1; i++) {
// find best pathing
ISolidlyRouterV2.route[] memory stableRoute = new ISolidlyRouterV2.route[](1);
stableRoute[0] = ISolidlyRouterV2.route(_path[i], _path[i + 1], true, factoryToUse);
ISolidlyRouterV2.route[] memory volatileRoute = new ISolidlyRouterV2.route[](1);
volatileRoute[0] = ISolidlyRouterV2.route(_path[i], _path[i + 1], false, factoryToUse);
uint256 amountStableOut = safeGetSolidlyV2AmountOut(_router, _amount, stableRoute);
uint256 amountVolatileOut = safeGetSolidlyV2AmountOut(_router, _amount, volatileRoute);
bool isStable = amountStableOut > amountVolatileOut;
_solidlyPath[i] = ISolidlyRouterV2.route(_path[i], _path[i + 1], isStable, factoryToUse);
if (isStable) {
_amount = amountStableOut;
} else {
_amount = amountVolatileOut;
}
}
return _solidlyPath;
}
function _estimateSwap(
SwapPath memory _swapPath,
uint256 _amount,
RouterType _type
) internal view virtual returns (uint256) {
address _fromToken = _swapPath.path[0];
address _toToken = _swapPath.path[_swapPath.path.length - 1];
// check for same token
if (_fromToken == _toToken) return _amount;
// Uniswap
if (_type == RouterType.UniV2) {
// can revert if pair doesn't exist
try IUniswapV2Router02(_swapPath.unirouter).getAmountsOut(_amount, _swapPath.path) returns (uint256[] memory amounts) {
return amounts[amounts.length - 1];
} catch {
return 0;
}
}
// Solidly
if (_type == RouterType.Solidly) {
// converting path
ISolidlyRouter.route[] memory _solidlyPath = _pathToSolidlyPath(_amount, _swapPath.unirouter, _swapPath.path);
// can revert if pair doesn't exist
try ISolidlyRouter(_swapPath.unirouter).getAmountsOut(_amount, _solidlyPath) returns (uint256[] memory amounts) {
return amounts[amounts.length - 1];
} catch {
return 0;
}
}
// Solidly V2
if (_type == RouterType.SolidlyV2) {
// converting path
ISolidlyRouterV2.route[] memory _solidlyPath = _pathToSolidlyV2Path(_amount, _swapPath.unirouter, _swapPath.path);
// can revert if pair doesn't exist
try ISolidlyRouterV2(_swapPath.unirouter).getAmountsOut(_amount, _solidlyPath) returns (uint256[] memory amounts) {
return amounts[amounts.length - 1];
} catch {
return 0;
}
}
return 0;
}
function _quoteAddLiquidity(
RouterType _type,
address _token0,
address _token1,
bool _isStable,
address _router,
address _toLpToken,
uint256 out0,
uint256 out1
)
internal
view
virtual
returns (
uint256 amountA,
uint256 amountB,
uint256 liquidity
)
{
if (_type == RouterType.Solidly) {
(amountA, amountB, liquidity) = ISolidlyRouterV2(_router).quoteAddLiquidity(_token0, _token1, _isStable, out0, out1);
}
if (_type == RouterType.SolidlyV2) {
(amountA, amountB, liquidity) = ISolidlyRouterV2(_router).quoteAddLiquidity(_token0, _token1, _isStable, IUniswapV2Pair(_toLpToken).factory(), out0, out1);
}
}
function _addRouter(address _router) internal virtual {
require(_router != address(0), 'invalid-router');
require(validRouter[_router] == false, 'router-already-added');
routers.push(_router);
validRouter[_router] = true;
whitelistedAddresses.add(_router);
}
}// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;
library console {
address constant CONSOLE_ADDRESS =
0x000000000000000000636F6e736F6c652e6c6f67;
function _sendLogPayloadImplementation(bytes memory payload) internal view {
address consoleAddress = CONSOLE_ADDRESS;
/// @solidity memory-safe-assembly
assembly {
pop(
staticcall(
gas(),
consoleAddress,
add(payload, 32),
mload(payload),
0,
0
)
)
}
}
function _castToPure(
function(bytes memory) internal view fnIn
) internal pure returns (function(bytes memory) pure fnOut) {
assembly {
fnOut := fnIn
}
}
function _sendLogPayload(bytes memory payload) internal pure {
_castToPure(_sendLogPayloadImplementation)(payload);
}
function log() internal pure {
_sendLogPayload(abi.encodeWithSignature("log()"));
}
function logInt(int256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(int256)", p0));
}
function logUint(uint256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function logString(string memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function logBool(bool p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function logAddress(address p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function logBytes(bytes memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes)", p0));
}
function logBytes1(bytes1 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0));
}
function logBytes2(bytes2 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0));
}
function logBytes3(bytes3 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0));
}
function logBytes4(bytes4 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0));
}
function logBytes5(bytes5 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0));
}
function logBytes6(bytes6 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0));
}
function logBytes7(bytes7 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0));
}
function logBytes8(bytes8 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0));
}
function logBytes9(bytes9 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0));
}
function logBytes10(bytes10 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0));
}
function logBytes11(bytes11 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0));
}
function logBytes12(bytes12 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0));
}
function logBytes13(bytes13 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0));
}
function logBytes14(bytes14 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0));
}
function logBytes15(bytes15 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0));
}
function logBytes16(bytes16 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0));
}
function logBytes17(bytes17 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0));
}
function logBytes18(bytes18 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0));
}
function logBytes19(bytes19 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0));
}
function logBytes20(bytes20 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0));
}
function logBytes21(bytes21 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0));
}
function logBytes22(bytes22 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0));
}
function logBytes23(bytes23 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0));
}
function logBytes24(bytes24 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0));
}
function logBytes25(bytes25 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0));
}
function logBytes26(bytes26 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0));
}
function logBytes27(bytes27 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0));
}
function logBytes28(bytes28 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0));
}
function logBytes29(bytes29 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0));
}
function logBytes30(bytes30 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0));
}
function logBytes31(bytes31 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0));
}
function logBytes32(bytes32 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0));
}
function log(uint256 p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256)", p0));
}
function log(string memory p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string)", p0));
}
function log(bool p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool)", p0));
}
function log(address p0) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address)", p0));
}
function log(uint256 p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1));
}
function log(uint256 p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1));
}
function log(uint256 p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1));
}
function log(uint256 p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1));
}
function log(string memory p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1));
}
function log(string memory p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1));
}
function log(string memory p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1));
}
function log(string memory p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1));
}
function log(bool p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1));
}
function log(bool p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1));
}
function log(bool p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1));
}
function log(bool p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1));
}
function log(address p0, uint256 p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1));
}
function log(address p0, string memory p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1));
}
function log(address p0, bool p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1));
}
function log(address p0, address p1) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1));
}
function log(uint256 p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2));
}
function log(uint256 p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2));
}
function log(uint256 p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2));
}
function log(uint256 p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2));
}
function log(uint256 p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2));
}
function log(uint256 p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2));
}
function log(uint256 p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2));
}
function log(uint256 p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2));
}
function log(uint256 p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2));
}
function log(uint256 p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2));
}
function log(string memory p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2));
}
function log(string memory p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2));
}
function log(string memory p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2));
}
function log(string memory p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2));
}
function log(string memory p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2));
}
function log(string memory p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2));
}
function log(string memory p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2));
}
function log(string memory p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2));
}
function log(string memory p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2));
}
function log(string memory p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2));
}
function log(string memory p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2));
}
function log(string memory p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2));
}
function log(string memory p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2));
}
function log(bool p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2));
}
function log(bool p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2));
}
function log(bool p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2));
}
function log(bool p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2));
}
function log(bool p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2));
}
function log(bool p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2));
}
function log(bool p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2));
}
function log(bool p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2));
}
function log(bool p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2));
}
function log(bool p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2));
}
function log(bool p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2));
}
function log(bool p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2));
}
function log(bool p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2));
}
function log(bool p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2));
}
function log(bool p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2));
}
function log(bool p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2));
}
function log(address p0, uint256 p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2));
}
function log(address p0, uint256 p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2));
}
function log(address p0, uint256 p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2));
}
function log(address p0, uint256 p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2));
}
function log(address p0, string memory p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2));
}
function log(address p0, string memory p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2));
}
function log(address p0, string memory p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2));
}
function log(address p0, string memory p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2));
}
function log(address p0, bool p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2));
}
function log(address p0, bool p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2));
}
function log(address p0, bool p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2));
}
function log(address p0, bool p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2));
}
function log(address p0, address p1, uint256 p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2));
}
function log(address p0, address p1, string memory p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2));
}
function log(address p0, address p1, bool p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2));
}
function log(address p0, address p1, address p2) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2));
}
function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3));
}
function log(uint256 p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3));
}
function log(string memory p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3));
}
function log(bool p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3));
}
function log(address p0, uint256 p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3));
}
function log(address p0, string memory p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3));
}
function log(address p0, bool p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, uint256 p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, string memory p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, bool p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, uint256 p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, string memory p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, bool p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3));
}
function log(address p0, address p1, address p2, address p3) internal pure {
_sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3));
}
}{
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"details": {
"constantOptimizer": true,
"cse": true,
"deduplicate": true,
"inliner": true,
"jumpdestRemover": true,
"orderLiterals": true,
"peephole": true,
"yul": true,
"yulDetails": {
"optimizerSteps": "u",
"stackAllocation": true
}
},
"runs": 200
},
"remappings": [],
"viaIR": true,
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_lpToken","type":"address"},{"indexed":true,"internalType":"address","name":"_customRouter","type":"address"}],"name":"CustomRouterSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_oldRouter","type":"address"},{"indexed":true,"internalType":"address","name":"_newRouter","type":"address"}],"name":"DefaultRouterChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_vault","type":"address"},{"indexed":true,"internalType":"address","name":"_want","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountIn","type":"uint256"}],"name":"ZapIn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"},{"indexed":true,"internalType":"address","name":"_vault","type":"address"},{"indexed":true,"internalType":"address","name":"_want","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amountOut","type":"uint256"}],"name":"ZapOut","type":"event"},{"inputs":[],"name":"USDC","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_router","type":"address"}],"name":"addRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"customRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"factoryToRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getBestSwapPath","outputs":[{"components":[{"internalType":"enum MatrixSwapHelperV2.RouterType","name":"routerType","type":"uint8"},{"internalType":"address","name":"unirouter","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"}],"internalType":"struct MatrixSwapHelperV2.SwapPath","name":"_bestSwapPath","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromToken","type":"address"},{"internalType":"address","name":"_toToken","type":"address"},{"internalType":"address","name":"_unirouter","type":"address"}],"name":"getSwapPath","outputs":[{"components":[{"internalType":"enum MatrixSwapHelperV2.RouterType","name":"routerType","type":"uint8"},{"internalType":"address","name":"unirouter","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"}],"internalType":"struct MatrixSwapHelperV2.SwapPath","name":"_swapUniV2Path","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhitelistedAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_path","type":"address[]"}],"name":"reversePath","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"routerToType","outputs":[{"internalType":"enum MatrixSwapHelperV2.RouterType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"routers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"address","name":"router","type":"address"}],"name":"setCustomRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromToken","type":"address"},{"internalType":"address","name":"_toToken","type":"address"},{"internalType":"address","name":"_unirouter","type":"address"},{"internalType":"address[]","name":"_path","type":"address[]"}],"name":"setSwapPath","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"sweepERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromLpToken","type":"address"},{"internalType":"address","name":"_toToken","type":"address"},{"internalType":"uint256","name":"_amountLpIn","type":"uint256"},{"internalType":"uint256","name":"_minAmountOut","type":"uint256"}],"name":"unzapFromLp","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_matrixVault","type":"address"},{"internalType":"address","name":"_toToken","type":"address"},{"internalType":"uint256","name":"_withdrawAmount","type":"uint256"},{"internalType":"uint256","name":"_minAmountOut","type":"uint256"}],"name":"unzapFromMatrix","outputs":[{"internalType":"uint256","name":"_amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validRouter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromToken","type":"address"},{"internalType":"address","name":"_toLpToken","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint256","name":"_minLpAmountOut","type":"uint256"}],"name":"zapToLp","outputs":[{"internalType":"uint256","name":"_lpAmountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromToken","type":"address"},{"internalType":"address","name":"_matrixVault","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint256","name":"_minLpAmountOut","type":"uint256"}],"name":"zapToMatrix","outputs":[{"internalType":"uint256","name":"_lpAmountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523462000027575b620000156200031b565b60405161512e62000d00823961512e90f35b62000030600080fd5b6200000b565b6200004c906200004f906001600160a01b031682565b90565b6001600160a01b031690565b6200004c9062000036565b6200004c906200005b565b906200007d9062000066565b600052602052604060002090565b906001600160a01b03905b9181191691161790565b90620000b46200004c620000bc9262000066565b82546200008b565b9055565b9060ff9062000096565b50634e487b7160e01b600052602160045260246000fd5b60041115620000ec57565b620000f6620000ca565b565b90620000f682620000e1565b6200004c90620000f8565b90620001236200004c620000bc9262000104565b8254620000c0565b50634e487b7160e01b600052604160045260246000fd5b50634e487b7160e01b600052603260045260246000fd5b6200017c60019162000169815490565b8410156200018557600052602060002090565b91020190600090565b6200018f62000142565b600052602060002090565b916001600160a01b0360089290920291821b911b62000096565b9190620001c96200004c620000bc9362000066565b9083546200019a565b90620001fe620000f6928054906801000000000000000082101562000205575b60018201815562000159565b90620001b4565b6200020f6200012b565b620001f2565b6200004c6200004c6200004c9290565b90601f01601f191681019081106001600160401b038211176200024757604052565b620002516200012b565b604052565b90620000f66200026560405190565b928362000225565b60209081906001600160401b0381116200028657020190565b620002906200012b565b020190565b90620002ab620002a5836200026d565b62000256565b918252565b369037565b90620000f6620002d0620002c98462000295565b936200026d565b601f190160208401620002b0565b9060208091620002ec845190565b811015620002fb575b02010190565b6200030562000142565b620002f5565b9062000317906200004f565b9052565b73a062ae8a9c5e11aaa026fc2670b0d65ccc8b28586200033b8162000517565b806200035d73f1046053aa5682b4f9a81b5481394da16be5ff5a600862000071565b906200036991620000a0565b600290816200037a82600762000071565b9062000386916200010f565b600090620003958183620001d2565b82739560e827af36c94d2ac33a39bce1fe78631088db620003b7818362000603565b5073c38464250f51123078bbd7ea574e185f6623d037948284620003dd88809662000603565b50620003e99162000603565b50620003f6600362000215565b916200040283620002b5565b73420000000000000000000000000000000000000694859485620004268a62000215565b620004329085620002de565b906200043e916200030b565b600192846200044d8562000215565b620004599083620002de565b9062000465916200030b565b82620004718762000215565b6200047d9083620002de565b9062000489916200030b565b620004979089848962000a94565b620004a290620002b5565b97620004ae9062000215565b620004ba9089620002de565b90620004c6916200030b565b620004d19062000215565b620004dd9087620002de565b90620004e9916200030b565b620004f49062000215565b620005009085620002de565b906200050c916200030b565b620000f69362000a94565b62000522906200052d565b620000f6336200058e565b620000f69062000551565b151590565b90620001236200004c620000bc9262000538565b620000f69062000563816000620001d2565b620005716001918262000071565b6200053d565b6200004c906200004f565b6200004c905462000577565b6200059a600562000582565b90620005a8816005620000a0565b620005df620005d87f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09362000066565b9162000066565b91620005ea60405190565b600090a3565b6200004c9081906001600160a01b031681565b906200063d62000639620006336200062d60006200004c9662000624600090565b5001946200005b565b620005f0565b62000215565b9190565b620006e1565b9160001960089290920291821b911b62000096565b9190620006736200066d620000bc936200004c565b6200004c565b90835462000643565b90620006a7620000f69280549068010000000000000000821015620002055760018201815562000159565b9062000658565b906200007d906200004c565b906000199062000096565b90620006d96200004c620000bc9262000215565b8254620006ba565b620006f5620006f183836200074a565b1590565b156200072f576200072a91620007249060016200071c846200071884826200067c565b5490565b9301620006ae565b620006c5565b600190565b5050600090565b6200004c9081565b6200004c905462000736565b6200076d91600162000767926200075f600090565b5001620006ae565b6200073e565b6200077d62000639600062000215565b141590565b6200004c90516200004f565b0190565b6020808252600c908201526b0d2dcecc2d8d2c85ae0c2e8d60a31b604082015260600190565b15620007c057565b60405162461bcd60e51b815280620007db6004820162000792565b0390fd5b50634e487b7160e01b600052601160045260246000fd5b81811062000802570390565b6200080c620007df565b0390565b6200004f6200004c6200004c9290565b6200004c9062000810565b6020808252600e908201526d34b73b30b634b216b937baba32b960911b604082015260600190565b156200085b57565b60405162461bcd60e51b815280620007db600482016200082b565b60601b90565b6200004c9062000876565b6200089662000317916200004f565b6200087c565b60149392620008b78583620008b782956200078e9762000887565b01809262000887565b6200004c606062000256565b906200031790620000f8565b6200004c9051620000f8565b90610100600160a81b039060081b62000096565b906200090c6200004c620000bc9262000066565b8254620008e4565b9190620006736200004c620000bc9362000215565b620000f69160009162000914565b81811062000943575050565b8062000953600060019362000929565b0162000937565b90918281106200096957505050565b620000f69290620009809092600052602060002090565b908101910162000937565b90620000f691680100000000000000008211620009af575b8054908281556200095a565b620009b96200012b565b620009a3565b620009ef620009e3620009d0845190565b93620009dd85856200098b565b60200190565b91600052602060002090565b600080925b84841062000a03575050505050565b600160208262000a2062000a18849562000782565b8688620001b4565b01930193019291620009f4565b90620000f691620009bf565b620000f6919062000a819060409060019062000a7a8162000a6562000a5e88620008d8565b826200010f565b62000a736020880162000782565b90620008f8565b0192015190565b9062000a2d565b90620000f69162000a39565b9262000c0a9162000c408462000c3962000c1662000acb9762000bb6620000f69a62000af562000ad862000ad260009d8e62000215565b8c620002de565b62000782565b62000aee62000ae7846200004f565b916200004f565b14620007b8565b62000b3062000b2162000ad262000acb62000b0e8d5190565b62000b1a600162000215565b90620007f6565b62000aee62000ae78b6200004f565b62000b5c62000b4962000b438d62000820565b6200004f565b62000b54856200004f565b141562000853565b60405162000b83816020810162000b76878d87846200089c565b9081038252038262000225565b62000b9762000b90825190565b9160200190565b209762000b7662000ba760405190565b9485936020850193846200089c565b62000bc362000b90825190565b209562000c1062000bd3620008c0565b62000be18b808301620008cc565b62000bf086602083016200030b565b62000bfc836040830152565b62000c0a60049889620006ae565b62000a88565b62000c6f565b9162000c2f62000c25620008c0565b98808a01620008cc565b602088016200030b565b6040860152565b620006ae565b600190801562000802570390565b600190600019811462000c65570190565b6200078e620007df565b9081519162000c7e83620002b5565b9062000c8b600062000215565b600162000c988162000215565b861062000cf75762000cf09162000ce362000cd162000ad262000cca62000cc362000ce99662000215565b8b620007f6565b87620002de565b62000cdd8388620002de565b6200030b565b62000c54565b9462000c46565b9362000c8b565b50919350505056fe6080604052600436101561001e575b361561001c5761001c600080fd5b005b60003560e01c8063067b5c86146101ea5780630d43b9dd146101e157806313684f18146101d85780634cd17e65146101cf5780634e9c1118146101c657806367970540146101bd5780636d028027146101b4578063715018a6146101ab57806371cd2d4a146101a257806389a30271146101995780638b4c5aee146101905780638da5cb5b1461018757806395e125cc1461017e578063a80bdc6514610175578063ad5c46481461016c578063c7d19aac14610163578063cc47c34c1461015a578063ccdc36f714610151578063d02170d814610148578063e00af4a71461013f578063f2fde38b14610136578063f4392fb31461012d5763ffa1ad740361000e57610128610ca1565b61000e565b50610128610b9e565b50610128610b1a565b50610128610af3565b50610128610abd565b50610128610a73565b50610128610a45565b50610128610a2a565b506101286109fb565b506101286109bf565b50610128610960565b50610128610936565b5061012861090c565b5061012861077b565b50610128610750565b506101286106eb565b506101286106b5565b50610128610620565b506101286105e4565b50610128610526565b506101286104be565b50610128610343565b50610128610289565b600080fd5b6001600160a01b031690565b90565b6001600160a01b0381165b036101f357565b9050359061022682610207565b565b80610212565b9050359061022682610228565b608081830312610278575b6102508282610219565b926102046102618460208501610219565b9361026f816040860161022e565b9360600161022e565b610280600080fd5b610246565b9052565b506102b56102a461029b36600461023b565b9291909161126a565b6040515b9182918290815260200190565b0390f35b906102049160208183031215610219576102d1600080fd5b610219565b610204906101f8906001600160a01b031682565b610204906102d6565b610204906102ea565b90610306906102f3565b600052602052604060002090565b610204916008021c6101f8565b906102049154610314565b6102049061033e6006916000926102fc565b610321565b503461037a575b6102b561036061035b3660046102b9565b61032c565b604051918291826001600160a01b03909116815260200190565b610382600080fd5b61034a565b90916060828403126103b8575b6102046103a18484610219565b936103af8160208601610219565b9360400161022e565b6103c0600080fd5b610394565b50634e487b7160e01b600052602160045260246000fd5b600411156103e657565b6102266103c5565b90610226826103dc565b610204906103ee565b610285906103f8565b0190565b9061042e61042761041d845190565b8084529260200190565b9260200190565b9060005b81811061043f5750505090565b90919261046561045e60019286516001600160a01b0316815260200190565b9460200190565b929101610432565b610204916040606082019261048a60008201516000850190610401565b6020818101516001600160a01b031690840152015190604081840391015261040e565b60208082526102049291019061046d565b50346104e8575b6102b56104dc6104d6366004610387565b91612360565b604051918291826104ad565b6104f0600080fd5b6104c5565b919061020490604084820312610519575b6105108185610219565b93602001610219565b610521600080fd5b610506565b5034610546575b61054161053b3660046104f5565b90612317565b604051005b61054e600080fd5b61052d565b90610204916020818303121561022e5761056b600080fd5b61022e565b50634e487b7160e01b600052603260045260246000fd5b6105a7600191610595815490565b8410156105b057600052602060002090565b91020190600090565b6105b8610570565b600052602060002090565b600080548210156105e157610204916105db91610587565b90610321565b80fd5b5034610601575b6102b56103606105fc366004610553565b6105c3565b610609600080fd5b6105eb565b6102049061033e6008916000926102fc565b503461063d575b6102b56103606106383660046102b9565b61060e565b610645600080fd5b610627565b600091031261065557565b610226600080fd5b9061066c61042761041d845190565b9060005b81811061067d5750505090565b90919261069c61045e60019286516001600160a01b0316815260200190565b929101610670565b60208082526102049291019061065d565b50346106de575b6106c736600461064a565b6102b56106d2613a16565b604051918291826106a4565b6106e6600080fd5b6106bc565b5034610705575b6106fd36600461064a565b610541610da2565b61070d600080fd5b6106f2565b9091606082840312610743575b61020461072c8484610219565b9361073a8160208601610219565b93604001610219565b61074b600080fd5b61071f565b503461076e575b6102b56104dc610768366004610712565b916110b5565b610776600080fd5b610757565b50346107aa575b61078d36600461064a565b6102b5737f5c764cbc14f9669b88837ca1490cca17c31607610360565b6107b2600080fd5b610782565b601f01601f191690565b50634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff8211176107fa57604052565b6108026107c1565b604052565b9061022661081460405190565b92836107d8565b6020809167ffffffffffffffff811161083357020190565b61083b6107c1565b020190565b909291926108556108508261081b565b610807565b9381855260208086019202830192818411610893575b915b83831061087a5750505050565b602080916108888486610219565b81520192019161086d565b61089b600080fd5b61086b565b906102049181601f820112156108bc575b602081359101610840565b6108c4600080fd5b6108b1565b90610204916020818303126108ff575b80359067ffffffffffffffff82116108f2575b016108a0565b6108fa600080fd5b6108ec565b610907600080fd5b6108d9565b5034610929575b6102b56106d26109243660046108c9565b613acf565b610931600080fd5b610913565b5034610953575b61094836600461064a565b6102b5610360610cea565b61095b600080fd5b61093d565b5034610981575b6102b56102a461097836600461023b565b92919091611e5b565b610989600080fd5b610967565b610204916008021c5b60ff1690565b90610204915461098e565b610204906109ba6001916000926102fc565b61099d565b50346109ee575b6102b56109dc6109d73660046102b9565b6109a8565b60405191829182901515815260200190565b6109f6600080fd5b6109c6565b5034610a1d575b610a0d36600461064a565b6102b56006602160991b01610360565b610a25600080fd5b610a02565b506102b56102a4610a3c36600461023b565b929190916116a1565b5034610a66575b6102b56102a4610a5d36600461023b565b92919091612081565b610a6e600080fd5b610a4c565b5034610a8e575b610541610a883660046104f5565b90612208565b610a96600080fd5b610a7a565b610204906109ba6007916000926102fc565b6020810192916102269190610401565b5034610ae6575b6102b5610ada610ad53660046102b9565b610a9b565b60405191829182610aad565b610aee600080fd5b610ac4565b5034610b0d575b610541610b083660046102b9565b612171565b610b15600080fd5b610afa565b5034610b34575b610541610b2f3660046102b9565b610e3e565b610b3c600080fd5b610b21565b608081830312610b91575b610b568282610219565b92610204610b678460208501610219565b93610b758160408601610219565b9360608101359067ffffffffffffffff82116108f257016108a0565b610b99600080fd5b610b4c565b5034610bbc575b610541610bb3366004610b41565b9291909161125e565b610bc4600080fd5b610ba5565b61040a60209167ffffffffffffffff8111610be857601f01601f191690565b6107b76107c1565b90610bfd61085083610bc9565b918252565b610c0c6001610bf0565b603360f81b602082015290565b610204610c02565b610204610c19565b610204610c21565b918091926000905b828210610c51575011610c4a575050565b6000910152565b91508060209183015181860152018291610c39565b610c876107b760209361040a93610c7b815190565b80835293849260200190565b95869101610c31565b602080825261020492910190610c66565b5034610cca575b610cb336600461064a565b6102b5610cbe610c29565b60405191829182610c90565b610cd2600080fd5b610ca8565b610204906101f8565b6102049054610cd7565b6102046005610ce0565b15610cfb57565b60405162461bcd60e51b815280610d44600482016020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b0390fd5b610d72610d53610cea565b610d6c610d5f336101f8565b916001600160a01b031690565b14610cf4565b610226610d90565b6101f86102046102049290565b61020490610d7a565b610226610d9d6000610d87565b610e77565b610226610d48565b61022690610db9610d53610cea565b610e19565b15610dc557565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b61022690610d9d610e2d6101f86000610d87565b6001600160a01b0383161415610dbe565b61022690610daa565b906001600160a01b03905b9181191691161790565b90610e6c610204610e73926102f3565b8254610e47565b9055565b610e816005610ce0565b90610e8d816005610e5c565b610ec0610eba7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936102f3565b916102f3565b91610eca60405190565b600090a3565b6102046060610807565b610ee2610ed0565b600080825260208201526060604082015290565b610204610eda565b610285906001600160a01b031660601b90565b60149392610f288583610f28829561040a97610efe565b018092610efe565b90610306565b6102046102046102049290565b61020490610997565b6102049054610f43565b90610285906103ee565b6102049060081c6101f8565b6102049054610f60565b90610f91610f8561041d845490565b92600052602060002090565b9060005b818110610fa25750505090565b909192610fcf610fc8600192610fb787610ce0565b6001600160a01b0316815260200190565b9460010190565b929101610f95565b9061020491610f76565b90610226610ffb92610ff260405190565b93848092610fd7565b03836107d8565b906102266110486001611013610ed0565b9461102661102082610f4c565b87610f56565b61104261103282610f6c565b6001600160a01b03166020880152565b01610fe1565b6040840152565b61020490611002565b90610bfd6108508361081b565b369037565b9061022661108061107a84611058565b9361081b565b601f190160208401611065565b906020809161109a845190565b8110156110a8575b02010190565b6110b0610570565b6110a2565b919290926110c1610ef6565b926110cb60405190565b6110eb81602081016110df868a8784610f11565b908103825203826107d8565b6110fd6110f6825190565b9160200190565b20906004956111166001611111858a610f30565b015490565b9260009361112a61112686610f36565b9190565b036112275750949550929361022693906006602160991b01806001600160a01b03841614158061120b575b156111d3576111aa906111976111bd9461118961118361117d6111786003610f36565b61106a565b98610f36565b8861108d565b906001600160a01b03169052565b6111896111a46001610f36565b8661108d565b6111896111b76002610f36565b8461108d565b60408501525b6001600160a01b03166020840152565b506111f4611201926111896111a46111ee6111786002610f36565b96610f36565b6111896111b76001610f36565b60408501526111c3565b506001600160a01b0381166001600160a01b0383161415611155565b9350505050610204925061123b9193610f30565b61104f565b90610226939291611252610d53610cea565b90610226939291613db2565b90610226939291611240565b92610226928261128493969561127e600090565b50612706565b61128e81946102f3565b33906112dc565b6112ae6112a86102049263ffffffff1690565b60e01b90565b6001600160e01b03191690565b6001600160a01b0390911681526040810192916102269160200152565b0152565b61131f600492611310610226956112f663a9059cbb611295565b9261130060405190565b96879460208601908152016112bb565b602082018103825203836107d8565b6113f0565b61132e6020610bf0565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602082015290565b610204611324565b801515610212565b905051906102268261135f565b9061020491602081830312156113675761138c600080fd5b611367565b1561139857565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b906113fd61140c926102f3565b90611406611357565b91611444565b805161141b6111266000610f36565b116114235750565b61143f816020611434610226945190565b818301019101611374565b611391565b61020492916114536000610f36565b9161151f565b1561146057565b60405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608490fd5b156114bb57565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b3d1561151a5761150f3d610bf0565b903d6000602084013e565b606090565b6102049392600092839291611540611536306102f3565b8290311015611459565b61155161154c84611568565b6114b4565b602082019151925af1611562611500565b9061157a565b3b6115766111266000610f36565b1190565b90919015611586575090565b81516115956111266000610f36565b11156115a45750805190602001fd5b610d44906115b160405190565b62461bcd60e51b815291829160048301610c90565b9050519061022682610207565b9061020491602081830312156115c6576115eb600080fd5b6115c6565b506040513d6000823e3d90fd5b9050519061022682610228565b9061020491602081830312156115fd57611622600080fd5b6115fd565b50634e487b7160e01b600052601160045260246000fd5b818110611649570390565b611651611627565b0390565b1561165c57565b60405162461bcd60e51b815260206004820152601760248201527f6465706f7369742d696e2d7661756c742d6661696c65640000000000000000006044820152606490fd5b919093926116ad600090565b506116bf6116ba866102f3565b6102f3565b631f1fcd51906116d86116d160405190565b9260e01b90565b8252602082600481845afa918215611cab575b600092611c89575b5081926117056116ba611749946102f3565b630dfe1681906117176116d160405190565b8252602082600481845afa918215611c7c575b600092611c5a575b5060405160209163d21220a7915b96879260e01b90565b825260049082905afa938415611c4d575b600094611c19575b5061176c906102f3565b91611776836102f3565b90611780306102f3565b9061178a60405190565b6370a0823160e01b81526001600160a01b038316600482015295602087602481875afa968715611c0c575b600097611be8575b506117c7906102f3565b966117d1886102f3565b946117db60405190565b6370a0823160e01b81526001600160a01b03851660048201529960208b6024818a5afa9a8b15611bdb575b60009b611bad575b509061182091836119f29b9c9d612706565b9161192560206118f4859f61183460405190565b6370a0823160e01b81526001600160a01b03891660048201528784826024818a5afa918215611ba0575b600092611b7f575b5061187a9192611875896102f3565b611d4d565b63b6b55f25853b15611b72575b61189a61189360405190565b9160e01b90565b815260048101889052600081602481838a5af18015611b65575b611b3f575b506040516370a0823160e01b81526001600160a01b03891660048201528381602481895afa908115611b32575b600091611b15575b5061163e565b6119086119016000610f36565b8211611655565b60405192839182919063a9059cbb60e01b835233600484016112bb565b03816000865af18015611b08575b611adc575b507ffb4595efc62c0b8b1567ac9769b05ea4215e28a83691f58ba050aa6981c7c3cb61197c61197261196c61196c336102f3565b946102f3565b946102a860405190565b0390a4602061198a60405190565b6370a0823160e01b81526001600160a01b038316600482015292839060249082905afa918215611acf575b600092611aaf575b50602091926119cb60405190565b968792839182916370a0823160e01b5b83526001600160a01b031660048301526024820190565b03915afa938415611aa2575b600094611a72575b50611a11838261163e565b611a1e6111266000610f36565b11611a5d575b505050611a31838261163e565b611a3e6111266000610f36565b11611a4857505050565b61022692611a559161163e565b9033906112dc565b611a6a92611a559161163e565b388080611a24565b611a9491945060203d8111611a9b575b611a8c81836107d8565b81019061160a565b9238611a06565b503d611a82565b611aaa6115f0565b6119fe565b60209250611ac990833d8111611a9b57611a8c81836107d8565b916119bd565b611ad76115f0565b6119b5565b611afc9060203d8111611b01575b611af481836107d8565b810190611374565b611938565b503d611aea565b611b106115f0565b611933565b611b2c9150843d8111611a9b57611a8c81836107d8565b386118ee565b611b3a6115f0565b6118e6565b611b589060005b611b5081836107d8565b81019061064a565b386118b9565b503d611b46565b611b6d6115f0565b6118b4565b611b7a600080fd5b611887565b61187a9250611b9a90863d8111611a9b57611a8c81836107d8565b91611866565b611ba86115f0565b61185e565b6119f29a9b509083611bd0611820949360203d8111611a9b57611a8c81836107d8565b9c9b5050909161180e565b611be36115f0565b611806565b6117c7919750611c059060203d8111611a9b57611a8c81836107d8565b96906117bd565b611c146115f0565b6117b5565b61176c919450611c3f9060203d8111611c46575b611c3781836107d8565b8101906115d3565b9390611762565b503d611c2d565b611c556115f0565b61175a565b6020919250611c7590823d8111611c4657611c3781836107d8565b9190611732565b611c846115f0565b61172a565b6117499250611ca59060203d8111611c4657611c3781836107d8565b916116f3565b611cb36115f0565b6116eb565b6001600160a01b039091168152604081019291610226916020905b01906001600160a01b03169052565b15611ce957565b60405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608490fd5b61131f60049261131061022695611d7a600084611d6982610f36565b8414918215611d87575b5050611ce2565b6112f663095ea7b3611295565b9091506020611d95896102f3565b63dd62ed3e90611dc1611da7306102f3565b92611dcc611db460405190565b9788958694859460e01b90565b845260048401611cb8565b03915afa918215611e1d575b600092611df5575b50611126611ded91610f36565b148438611d73565b611ded919250611e156111269160203d8111611a9b57611a8c81836107d8565b929150611de0565b611e256115f0565b611dd8565b6001600160a01b0390911681526060810193926102269290916040916112d8905b6001600160a01b03166020830152565b6116ba611e749195949395611e6e600090565b506102f3565b91631f1fcd5190611e876116d160405190565b8252602082600481875afa918215612074575b60009261204e575b50611f73611f8e9293602060006323b872dd99339a838c8b611ee3611ec6306102f3565b968795611eee88611ed660405190565b9889978896879560e01b90565b855260048501611e2a565b03925af18015612041575b612026575b506000611f28632e1a7d4d8b3b15612019575b611f36611f1d60405190565b948593849360e01b90565b835260048301526024820190565b0381838d5af1801561200c575b611ff6575b50611f556116ba886102f3565b6119db6370a08231611f6660405190565b9687948593849360e01b90565b03915afa918215611fe9575b600092611fc9575b50846132fd565b918294611fc461197261196c61196c7fb6b31433b0feeb179e7bdaf74af8f681471ac78f86bddc6e35ab7f514f84af03946102f3565b0390a4565b611fe291925060203d8111611a9b57611a8c81836107d8565b9038611f87565b611ff16115f0565b611f7f565b612006906000611b5081836107d8565b38611f48565b6120146115f0565b611f43565b612021600080fd5b611f11565b61203c90843d8111611b0157611af481836107d8565b611efe565b6120496115f0565b611ef9565b611f8e925061206d611f739160203d8111611c4657611c3781836107d8565b9250611ea2565b61207c6115f0565b611e9a565b610204939291906120a583612095836102f3565b3361209f306102f3565b916120aa565b6132fd565b9061131f90611310610226956004956120c66323b872dd611295565b936120d060405190565b9788956020870190815201611e2a565b610226906120ef610d53610cea565b61212a610226916120ff816102f3565b6020339261210c836102f3565b6119db6370a0823161211d60405190565b9788948593849360e01b90565b03915afa928315612164575b600093612144575b506112dc565b61215d91935060203d8111611a9b57611a8c81836107d8565b913861213e565b61216c6115f0565b612136565b610226906120e0565b906102269161218a610d53610cea565b6121c9565b1561219657565b60405162461bcd60e51b815260206004820152600b60248201526a185b1c9958591e4b5cd95d60aa1b6044820152606490fd5b906122036102269260086121fe6121e86121e384846102fc565b610ce0565b6121f8610d5f6101f86000610d87565b1461218f565b6102fc565b610e5c565b906102269161217a565b9061022691612222610d53610cea565b61223f565b6001906000198114612237570190565b61040a611627565b9160009161224c83610f36565b612257610204855490565b8110156123065761226b6105db8286610587565b61227d6001600160a01b038416610d5f565b146122f2576122a0610204612290865490565b61229a6001610f36565b9061163e565b81146122b4576122af90612227565b61224c565b60405162461bcd60e51b81526020600482015260166024820152751c9bdd5d195c8b5b9bdd0b5dda1a5d195b1a5cdd195960521b6044820152606490fd5b5090926102269250612203905b60066102fc565b5090926102269250612203906122ff565b9061022691612212565b61020490610fe1565b1561233157565b60405162461bcd60e51b81526020600482015260076024820152660dcde5ae0c2e8d60cb1b6044820152606490fd5b909261236a610ef6565b9260009061237782612321565b9561238183610f36565b93845b61238f6102048a5190565b81101561257f576123b06123a3828b61108d565b516001600160a01b031690565b6123bb81858a6110b5565b906123cf6123ca8260076102fc565b610f4c565b916123db838883614be1565b898111612573575b5089929190506006602160991b01806001600160a01b03851614159081612556575b506124e0575b87737f5c764cbc14f9669b88837ca1490cca17c31607806001600160a01b0386161415806124c4575b61244c575b505050505061244790612227565b612384565b9161249e916124786124a595946111f4612464610ef6565b986111896111a46111ee6111786003610f36565b612489896111896111b76002610f36565b60408601526001600160a01b03166020850152565b8683614be1565b8781116124b6575b80878a93612439565b9098509550612447386124ad565b506001600160a01b0381166001600160a01b0389161415612434565b9091506124eb610ef6565b6124f86111786002610f36565b6125088b6111896111b78c610f36565b612519876111896111b76001610f36565b60408201526001600160a01b0382166020820152612538838883614be1565b89811161254a575b505090889161240b565b909a5097508838612540565b6001600160a01b031690506001600160a01b038716141538612405565b909a50975088386123e3565b5096505050610204925061112661259591610f36565b1161232a565b156125a257565b60405162461bcd60e51b815260206004820152601260248201527134b73b30b634b216b33937b696ba37b5b2b760711b6044820152606490fd5b156125e357565b60405162461bcd60e51b815260206004820152601160248201527034b73b30b634b216b0b6b7bab73a16b4b760791b6044820152606490fd5b50634e487b7160e01b600052601260045260246000fd5b811561263d570490565b61264561261c565b0490565b806000190482118115151661265c570290565b612664611627565b0290565b60ff8116610212565b9050519061022682612668565b90610204916020818303121561267157612696600080fd5b612671565b60ff16604d81116126ad575b600a0a90565b6126b5611627565b6126a7565b81198111612237570190565b156126cd57565b60405162461bcd60e51b8152602060048201526011602482015270736c6970706167652d72656b742d796f7560781b6044820152606490fd5b929392916000916000913461271a84610f36565b811115612ed0578361276e6127526116ba6006602160991b01612747816001600160a01b038d161461259b565b6116ba8688146125dc565b63d0e30db0813b15612ec3575b6040515b948593849260e01b90565b82526004925af18015612eb6575b612e9a575b505b61278c82612f24565b94859361279b6116ba856102f3565b90630dfe1681946127b56127ae60405190565b9660e01b90565b8652602086600481865afa958615612e8d575b600096612e6d575b5063d21220a7976127ea6127e360405190565b9960e01b90565b8952602089600481875afa988915612e60575b600099612e32575b50918791878a96959460029561282d61282661282089610f36565b8c612633565b848a612360565b61285361284c6128468d6128408c610f36565b90612633565b8d61163e565b8b8b612360565b92508986996007936128686123ca8b876102fc565b9060019161287e612878846103ee565b916103ee565b148c8c8215612e0e575b5050612da8575b508d8c612a8057505050506128a388610f36565b6128ad908c612633565b60208201516001600160a01b03166128c590846102fc565b6128ce90610f4c565b906128d8926140ea565b996128e38b98610f36565b6128ed9082612633565b6128f69161163e565b9061290b60208401516001600160a01b031690565b612914916102fc565b61291d90610f4c565b90612927926140ea565b6102269c6129fe9c611875839861296b986116ba986118756129636129576129516116ba9b6102f3565b93610f36565b966116ba888686611d4d565b958387611d4d565b936370a082319361297b306102f3565b9661298560405190565b986129908760e01b90565b8a526001600160a01b03891660048b015260208a6024818b5afa998a15612a73575b60009a612a35575b50936129e59896936129d49360209997936119db97613131565b6040515b9586948593849360e01b90565b03915afa908115612a28575b600091612a10575061163e565b612a09611126829590565b10156126c6565b611b2c915060203d8111611a9b57611a8c81836107d8565b612a306115f0565b6129f1565b6119db95919a50936129d4936020999793612a616129e59c9a978c3d8111611a9b57611a8c81836107d8565b9c9397509397995093509396986129ba565b612a7b6115f0565b6129b2565b91888b879d9387878b8b8e998a612ab0612b6c9d9e9f9b612aa3612aa991610f36565b84612633565b809361163e565b956001600160a01b038b166001600160a01b03831614612d9757612b3e6020612b266116ba612b20612b0986612b5d99612b036123ca8d612afd8a6128409d01516001600160a01b031690565b906102fc565b91614be1565b612b1a670de0b6b3a7640000610f36565b90612649565b956102f3565b63313ce56790612b3560405190565b93849260e01b90565b825260049082905afa908115612d5b575b600091612d2d575b5061269b565b9a8b986001600160a01b031690565b6001600160a01b03841614612d8c576020612b266116ba612b20612b0986612bae99612b036123ca612b3e99612afd8a6128409d01516001600160a01b031690565b9788955b83612bbc916102fc565b612bc590610f4c565b96612bcf97614f21565b509190928c670de0b6b3a764000094612be786610f36565b612bf091612649565b612bf9896102f3565b612c02906102f3565b63313ce56790612c1160405190565b90612c1c8360e01b90565b8252816004815a93602094fa9182156116ba612c62612c58612c7097612840612b3e98602098612c6897612d7f575b600091612d68575061269b565b9a612b1a8d610f36565b966102f3565b604051612b35565b612c7991612633565b91612c8385610f36565b612c8c91612649565b90612c9691612633565b90612ca091612649565b90612caa91612633565b612cb382610f36565b612cbd908d612649565b91612cc790610f36565b612cd0916126ba565b612cd991612633565b998a612ce49161163e565b99612cf960208301516001600160a01b031690565b612d0390896102fc565b612d0c90610f4c565b90612d16926140ea565b98899661290b60208401516001600160a01b031690565b612d4e915060203d8111612d54575b612d4681836107d8565b81019061267e565b38612b57565b503d612d3c565b612d636115f0565b612b4f565b612d4e9150893d8111612d5457612d4681836107d8565b612d876115f0565b612c4b565b505050978895612bb2565b50509a8b986001600160a01b031690565b612dc0919c506020906322be3de190612b3560405190565b825260049082908d905af1908115612e01575b600091612de3575b509a3861288f565b612dfb915060203d8111611b0157611af481836107d8565b38612ddb565b612e096115f0565b612dd3565b612e2a919250612e246123ca612878928b6102fc565b926103ee565b148c8c612888565b87995091612e538993602097969593973d8111611c4657611c3781836107d8565b9950919490929394612805565b612e686115f0565b6127fd565b612e8691965060203d8111611c4657611c3781836107d8565b94386127d0565b612e956115f0565b6127c8565b612eb090843d8611611b5e57611b5081836107d8565b38612781565b612ebe6115f0565b61277c565b612ecb600080fd5b61275f565b50612ede81612095876102f3565b612783565b15612eea57565b60405162461bcd60e51b81526020600482015260126024820152713ab739bab83837b93a32b216b937baba32b960711b6044820152606490fd5b600690612f346121e382846102fc565b91612f3f6000610d87565b92612f526001600160a01b038516610d5f565b03612ffc5750612f88610204926020612f706116ba6121e3956102f3565b63c45a015590612f7f60405190565b94859260e01b90565b825260049082905afa918215612fef575b600092612fcf575b506121fe600891612fc8610d5f612fbb6121e387876102fc565b926001600160a01b031690565b1415612ee3565b612fe891925060203d8111611c4657611c3781836107d8565b9038612fa1565b612ff76115f0565b612f99565b6102049250906121e3916102fc565b909160608284031261303c575b61020461302584846115fd565b9361303381602086016115fd565b936040016115fd565b613044600080fd5b613018565b61028590610f36565b9694929099989795939161012088019a60008901613077916001600160a01b03169052565b6001600160a01b03166020880152151560408701526060860152608085015260a084016130a391613049565b60c083016130b091613049565b6001600160a01b031660e08201526101000152565b95939198979694929098610100870199600088016130ea916001600160a01b03169052565b6001600160a01b0316602087015260408601525b60608501526080840161311091613049565b60a0830161311d91613049565b6001600160a01b031660c082015260e00152565b9394909291946131456123ca8660076102fc565b91600092613152846103ee565b61315b826103ee565b036131f9575050906131a3916131ae6131786116ba6060986102f3565b9463e8e3370092848061318a306102f3565b92429461319660405190565b9d8e9c8d9b8c9a60e01b90565b8a5260048a016130c5565b03925af180156131ec575b6131c05750565b6131e09060603d81116131e5575b6131d881836107d8565b81019061300b565b505050565b503d6131ce565b6131f46115f0565b6131b9565b6132076001949392946103ee565b613210826103ee565b149081156132a5575b501561326a576131ae61325f936132346116ba6060996102f3565b958480635a47ddc395613246306102f3565b93429561325260405190565b9e8f9d8e9c8d9b60e01b90565b8b5260048b01613052565b60405162461bcd60e51b8152602060048201526013602482015272696e76616c69642d726f757465722d7479706560681b6044820152606490fd5b90506132b461287860026103ee565b1438613219565b156132c257565b60405162461bcd60e51b8152602060048201526013602482015272199d1b4b5d1c985b9cd9995c8b59985a5b1959606a1b6044820152606490fd5b906133b491819395949561330f600090565b5061331982612f24565b916133266116ba826102f3565b90630dfe16819261334061333960405190565b9460e01b90565b8452602084600481865afa938415613805575b6000946137e3575b50613528939463d21220a79161337a61337360405190565b9360e01b90565b8352602083600481885afa9283156137d6575b6000936137a8575b506133bb81836133a86133f196976102f3565b61187560009d8e610f36565b8383611d4d565b83878a938b6007986133d06123ca848c6102fc565b6133dd61287860016103ee565b148015613787575b613724575b50506138e5565b6133fd6116ba856102f3565b916134f461344e6370a0823196613413306102f3565b9a8b9160206119db8b61343361342860405190565b968793849360e01b90565b03818b5afa928315613717575b6000936136f7575b50612360565b916134da61348f8b8a6134636116ba896102f3565b9760206119db8d61347661342860405190565b03818c5afa928315613717576000936136f75750612360565b9360208c6134cc6123ca6134b86123ca6134b2868801516001600160a01b031690565b896102fc565b96612afd858b01516001600160a01b031690565b986119db8c611f6660405190565b03915afa9182156136ea575b6000926136ca575b506140ea565b50602061350060405190565b809361350c8860e01b90565b82526001600160a01b038b1660048301528180602481016134da565b5060206119db61353a6116ba856102f3565b9261355261354760405190565b978893849360e01b90565b0381845afa9384156136bd575b60009461369d575b50613579613573859790565b85612a09565b6006602160991b019161358b83610d5f565b036136305750610226926135bb836135a66116ba82956102f3565b632e1a7d4d90803b1561362357604051612b35565b825260048201859052602490829084905af18015613616575b6135fa575b5033906135e560405190565b90818003925af16135f4611500565b506132bb565b61361090833d8511611b5e57611b5081836107d8565b386135d9565b61361e6115f0565b6135d4565b61362b600080fd5b612c68565b602092915061365963a9059cbb92339361366461364c60405190565b9788968795869460e01b90565b8452600484016112bb565b03925af18015613690575b6136765750565b61368d9060203d8111611b0157611af481836107d8565b50565b6136986115f0565b61366f565b6136b691945060203d8111611a9b57611a8c81836107d8565b9238613567565b6136c56115f0565b61355f565b6136e391925060203d8111611a9b57611a8c81836107d8565b90386134ee565b6136f26115f0565b6134e6565b61371091935060203d8111611a9b57611a8c81836107d8565b9138613448565b61371f6115f0565b613440565b60209192965061373c906322be3de161276360405190565b82526004925af190811561377a575b60009161375c575b50938b386133ea565b613774915060203d8111611b0157611af481836107d8565b38613753565b6137826115f0565b61374b565b506137956123ca848c6102fc565b6137a261287860026103ee565b146133e5565b6133f1935081836133a86137cc6133bb9460203d8111611c4657611c3781836107d8565b9650505050613395565b6137de6115f0565b61338d565b61352894506137ff9060203d8111611c4657611c3781836107d8565b9361335b565b61380d6115f0565b613353565b919061020490604084820312613836575b61382d81856115fd565b936020016115fd565b61383e600080fd5b613823565b9593919897969492909861010087019960008801613868916001600160a01b03169052565b6001600160a01b03166020870152151560408601526130fe565b949290979695939160e0860198600087016138a4916001600160a01b03169052565b6001600160a01b031660208601526040850152606084016138c491613049565b608083016138d191613049565b6001600160a01b031660a082015260c00152565b939091936138f76123ca8260076102fc565b91600092613904846103ee565b61390d826103ee565b036139a9575050604093916139276116ba613954936102f3565b9261395f63baa2abde9161393a306102f3565b8480429361394760405190565b9c8d9b8c9a8b9960e01b90565b895260048901613882565b03925af1801561399c575b6139715750565b6139919060403d8111613995575b61398981836107d8565b810190613812565b5050565b503d61397f565b6139a46115f0565b61396a565b6139b660019492946103ee565b6139bf826103ee565b14908115613a00575b501561326a5760409461395f6139e36116ba6139f5956102f3565b94630dede6c492848061318a306102f3565b8a5260048a01613843565b9050613a0f61287860026103ee565b14386139c8565b6102046060613a256002613aad565b905090565b6102049081565b6102049054613a2a565b90613a4a610f8561041d845490565b9060005b818110613a5b5750505090565b909192613a78610fc8600192613a7087613a31565b815260200190565b929101613a4e565b9061020491613a3b565b90610226610ffb92613a9b60405190565b93848092613a80565b61020490613a8a565b600061020491613abb606090565b5001613aa4565b6001908015611649570390565b90815191613adc8361106a565b90613ae76000610f36565b6001613af281610f36565b8610613b3b57613b3591613b2a613b206123a3613b1a613b14613b2f96610f36565b8b61163e565b8761108d565b611189838861108d565b612227565b94613ac2565b93613ae7565b509193505050565b15613b4a57565b60405162461bcd60e51b815260206004820152600c60248201526b0d2dcecc2d8d2c85ae0c2e8d60a31b6044820152606490fd5b15613b8557565b60405162461bcd60e51b815260206004820152600e60248201526d34b73b30b634b216b937baba32b960911b6044820152606490fd5b61020490516103ee565b9060ff90610e52565b90613bde610204610e73926103f8565b8254613bc5565b90610100600160a81b039060081b610e52565b90613c08610204610e73926102f3565b8254613be5565b9160001960089290920291821b911b610e52565b9190613c34610204610e7393610f36565b908354613c0f565b61022691600091613c23565b818110613c53575050565b80613c616000600193613c3c565b01613c48565b9091828110613c7557505050565b6102269290613c8390610f85565b9081019101613c48565b9061022691680100000000000000008211613cae575b805490828155613c67565b613cb66107c1565b613ca3565b916001600160a01b0360089290920291821b911b610e52565b9190613ce5610204610e73936102f3565b908354613cbb565b613d18613d0c613cfb845190565b93613d068585613c8d565b60200190565b91600052602060002090565b600080925b848410613d2b575050505050565b6001602082613d4c613d458495516001600160a01b031690565b8688613cd4565b01930193019291613d1d565b9061022691613ced565b6102269190613da290604090600190613d9b81613d87613d8188613bbb565b82613bce565b60208701516001600160a01b031690613bf8565b0192015190565b90613d58565b9061022691613d62565b92613eca91613eeb84613ee4613ecf613dde97613e806102269a613dfc613de46123a360009d8e610f36565b8c61108d565b613df66001600160a01b038416610d5f565b14613b43565b613e22613e106123a3613dde6122908d5190565b613df66001600160a01b038b16610d5f565b613e42613e316101f88d610d87565b6001600160a01b0385161415613b7e565b604051613e5981602081016110df878d8784610f11565b613e646110f6825190565b20976110df613e7260405190565b948593602085019384610f11565b613e8b6110f6825190565b2095610924613e98610ed0565b613ea48b808301610f56565b6001600160a01b0386166020820152613ebe836040830152565b613eca60049889610f30565b613da8565b91611032613edb610ed0565b98808a01610f56565b6040860152565b610f30565b90613eff61042761041d845190565b9060005b818110613f105750505090565b909192613f5661045e600192865180516001600160a01b039081168352602080830151821690840152604080830151151590840152606091820151169082015260800190565b929101613f03565b90613f996112d89161022696989795613f8c608096613f8260a08801946000890152565b6020870190613049565b8482036040860152613ef0565b6001600160a01b039097166060830152565b80516001600160a01b03168252610226919060409081906020818101516001600160a01b03169085015201511515910152565b9061040a81606093613fab565b90613ffa61042761041d845190565b9060005b81811061400b5750505090565b90919261401e61045e6001928651613fde565b929101613ffe565b90613f996112d8916102269698979561404a608096613f8260a08801946000890152565b8482036040860152613feb565b91946140a96140976112d89360a09661408a6102269a9c9b999c61408060c08a019460008b0152565b6020890190613049565b868203604088015261065d565b6001600160a01b039099166060850152565b6001600160a01b03166080830152565b90613f996112d891610226969897956140dd608096613f8260a08801946000890152565b848203604086015261065d565b909190604081019283519361410d6123a360009661410788610f36565b9061108d565b948151956141306123a361412085515190565b9861410760019a61229a8c610f36565b906001600160a01b0382166001600160a01b038216146144a857614199916116ba602061415f6116ba946102f3565b9801976141866141768a516001600160a01b031690565b61417f88610f36565b9083611d4d565b88516001600160a01b0316861991611d4d565b926370a08231926141a9306102f3565b956141b360405190565b976141be8660e01b90565b89526001600160a01b03881660048a01526020896024818a5afa98891561449b575b60009961447b575b506141f2856103ee565b6141fb826103ee565b036142b257509261020498816119db946129e59997946142568361422f6116ba6116ba60209e9c516001600160a01b031690565b92614261635c11d79591518d4291873b156142a5575b6040515b9a8b998a98899760e01b90565b8752600487016140b9565b03925af18015614298575b61427b575b50506040516129d8565b8161429192903d10611b5e57611b5081836107d8565b3880614271565b6142a06115f0565b61426c565b6142ad600080fd5b614245565b6142bc60036103ee565b6142c5826103ee565b0361437957509261020498816119db946129e5999794614320836142f96116ba6116ba60209e9c516001600160a01b031690565b9261432b63ac3893ba91518d804292883b1561436c575b6040519b8c9a8b998a9860e01b90565b885260048801614057565b03925af1801561435f575b614342575b50506129d4565b8161435892903d10611b5e57611b5081836107d8565b388061433b565b6143676115f0565b614336565b614374600080fd5b614310565b6143828a6103ee565b61438b826103ee565b0361440457509261020498816119db946129e59997946143f9838961432b6143e76143c760209f9d6116ba6116ba91516001600160a01b031690565b956143de636cc1ae1394516001600160a01b031690565b90519088614568565b8d4291873b156142a557604051614249565b875260048701614026565b614419612878600299979495989693996103ee565b0361326a5761020498816020976119db95614470838c61432b6143e76129e59f6116ba6116ba61445092516001600160a01b031690565b956144676388cd821e94516001600160a01b031690565b90519088614765565b875260048701613f5e565b61449491995060203d8111611a9b57611a8c81836107d8565b97386141e8565b6144a36115f0565b6141e0565b505050509250505090565b6144bb610ed0565b906000825260208080840160005b8152016000905250565b6102046144b3565b60005b8281106144ea57505050565b6020906144f56144d3565b81840152016144de565b9061022661450f61107a84611058565b601f1901602084016144db565b919061020490604084820312614540575b61453781856115fd565b93602001611367565b614548600080fd5b61452d565b908152606081019392610226929091604091611cd390611e4b565b909161458291815190614587600194859361229a85610f36565b6144ff565b946000925b614599575b505050505090565b6145b06102046145a7865190565b61229a88610f36565b8310156146ed576146a985604081946145cb6116ba866102f3565b61460b635e1e63256146166145fb6123a38d6141078e6145f56145ef85838661108d565b9c610f36565b906126ba565b6040519788968795869560e01b90565b85526004850161454d565b03915afa9081156146e0575b6000809190926146b0575b5061468d61463e6123a3888a61108d565b9161468461465a6123a3613dde6146548b610f36565b8c6126ba565b614674614665610ed0565b6001600160a01b039096168652565b6001600160a01b03166020850152565b15156040830152565b614697868a61108d565b526146a2858961108d565b5093612227565b929161458c565b90506146d3915060403d81116146d9575b6146cb81836107d8565b81019061451c565b3861462d565b503d6146c1565b6146e86115f0565b614622565b614591565b6102046080610807565b6147046146f2565b906000825260208080808501600081520160006144c9565b6102046146fc565b60005b82811061473357505050565b60209061473e61471c565b8184015201614727565b9061022661475861107a84611058565b601f190160208401614724565b6147869260206147776116ba856102f3565b63d4b6846d9061174060405190565b825260049082905afa938415614a2c575b600094614a06575b5090816147ad6147bf935190565b916147c4600194859461229a86610f36565b614748565b956000935b6147d7575b50505050505090565b6147e56102046145a7855190565b841015614a015784916147f783610f36565b61480081614748565b9061480b878761108d565b516001600160a01b031661481f82896126ba565b614829908861108d565b516001600160a01b031661483b6146f2565b6001600160a01b0390921682526001600160a01b0316602082015285151560408201526001600160a01b038516606082015260009061487982610f36565b614883908561108d565b5261488d81610f36565b614897908461108d565b506148a182614748565b926148ac898961108d565b516001600160a01b03166148c0848b6126ba565b6148ca908a61108d565b516001600160a01b03166148dc6146f2565b6001600160a01b03909216848301526001600160a01b0316602082015282151560408201526001600160a01b038716606082015261491983610f36565b614923908661108d565b5261492d82610f36565b614937908561108d565b5061494390858c614b18565b938493614950918c614b18565b9384109161495e898961108d565b516001600160a01b031690614973908a6126ba565b61497d908961108d565b516001600160a01b0316906149906146f2565b928301906149a691906001600160a01b03169052565b6001600160a01b0316602082015281151560408201526001600160a01b03851660608201526149d5888c61108d565b526149e0878b61108d565b506149f29290156149f9575094612227565b93916147c9565b905094612227565b6147ce565b6147bf92919450614a249060203d8111611c4657611c3781836107d8565b93909161479f565b614a346115f0565b614797565b90929192614a496108508261081b565b9381855260208086019202830192818411614a87575b915b838310614a6e5750505050565b60208091614a7c84866115fd565b815201920191614a61565b614a8f600080fd5b614a5f565b906102049181601f82011215614ab0575b602081519101614a39565b614ab8600080fd5b614aa5565b9061020491602081830312614af3575b80519067ffffffffffffffff8211614ae6575b01614a94565b614aee600080fd5b614ae0565b614afb600080fd5b614acd565b90815260406020820181905261020492910190613ef0565b929190600090614b2a6116ba83612c62565b614b4b635509a1ac614b56614b3e60405190565b9687958694859460e01b90565b845260048401614b00565b03915afa60009181614b8e575b50614b75575090506102046000610f36565b61020491925080614107612290614b8a935190565b5190565b614baa91923d8091833e614ba281836107d8565b810190614abd565b9038614b63565b9081526040602082018190526102049291019061065d565b90815260406020820181905261020492910190613feb565b91906040830190815193614bfd6123a360009661410788610f36565b93835194614c26610d5f6101f86123a3614c1689515190565b9961410760019b61229a8d610f36565b14614e6657614c34866103ee565b614c3d826103ee565b14614de5575b614c4c856103ee565b614c55826103ee565b14614d2d575b614c6861287860026103ee565b14614c7b575b5050505061020490610f36565b90614cb66116ba6116ba614ca8602089960196614c9f88516001600160a01b031690565b90519086614765565b95516001600160a01b031690565b614b4b635509a1ac614cca614b3e60405190565b03915afa60009181614d12575b50614cf55750614cec57610204388080614c6e565b61020490610f36565b6102049250614107614b8a9261229a614d0c845190565b91610f36565b614d2691923d8091833e614ba281836107d8565b9038614cd7565b614d868660208401614d696116ba6116ba614d5b614d5285516001600160a01b031690565b8b51908b614568565b93516001600160a01b031690565b614d7a639881fcb46129d860405190565b83528a60048401614bc9565b03915afa60009181614dc9575b50614dad57508415614c5b57505050505061020490610f36565b93505050506102049250614107614b8a9261229a614d0c845190565b614dde9192503d808a833e614ba281836107d8565b9038614d93565b614e2486614e036116ba6116ba60208701516001600160a01b031690565b63d06ca61f90614e188851926129d860405190565b83528a60048401614bb1565b03915afa60009181614e4b575b50614dad57508415614c4357505050505061020490610f36565b614e5f91923d8091833e614ba281836107d8565b9038614e31565b50509250505090565b9095949261022694614eb76112d892614eae608096614e9e60a088019c60008901906001600160a01b03169052565b6001600160a01b03166020870152565b15156040850152565b6060830152565b9194614f1a6112d892989795614f0a60a096614f016102269a614ef160c08a019e60008b01906001600160a01b03169052565b6001600160a01b03166020890152565b15156040870152565b6001600160a01b03166060850152565b6080830152565b959697949092919397614f32600090565b9788998998614f4160016103ee565b614f4a826103ee565b1461505a575b614f5d61287860026103ee565b14614f6c575b50505050505050565b614fcc95979a50614fd7939496995060609850614f8e6116ba614fa2926102f3565b966020612f706116ba63ce700c29986102f3565b825260049082905afa91821561504d575b60009261502d575b506040519a8b998a98899860e01b90565b885260048801614ebe565b03915afa8015615020575b6000808091939092614fff575b5090919238808080808080614f63565b91505061501a915060603d81116131e5576131d881836107d8565b38614fef565b6150286115f0565b614fe2565b61504691925060203d8111611c4657611c3781836107d8565b9038614fbb565b6150556115f0565b614fb3565b9a5061506a9199508098506102f3565b615073906102f3565b976398a0fb3c9861508360405190565b9960e01b8a52898061509c8585898c8c60048701614e6f565b03815a93606094fa9788156150eb575b60008080919b909a6150c2575b5098999a614f50565b919950506150df91995060603d81116131e5576131d881836107d8565b389a929a9991996150b9565b6150f36115f0565b6150ac56fea2646970667358221220421276f12fe068ca0f7c2f7975947bc8f6a9003b7aee217fb0a2d2739582f68c64736f6c634300080e0033
Deployed Bytecode
0x6080604052600436101561001e575b361561001c5761001c600080fd5b005b60003560e01c8063067b5c86146101ea5780630d43b9dd146101e157806313684f18146101d85780634cd17e65146101cf5780634e9c1118146101c657806367970540146101bd5780636d028027146101b4578063715018a6146101ab57806371cd2d4a146101a257806389a30271146101995780638b4c5aee146101905780638da5cb5b1461018757806395e125cc1461017e578063a80bdc6514610175578063ad5c46481461016c578063c7d19aac14610163578063cc47c34c1461015a578063ccdc36f714610151578063d02170d814610148578063e00af4a71461013f578063f2fde38b14610136578063f4392fb31461012d5763ffa1ad740361000e57610128610ca1565b61000e565b50610128610b9e565b50610128610b1a565b50610128610af3565b50610128610abd565b50610128610a73565b50610128610a45565b50610128610a2a565b506101286109fb565b506101286109bf565b50610128610960565b50610128610936565b5061012861090c565b5061012861077b565b50610128610750565b506101286106eb565b506101286106b5565b50610128610620565b506101286105e4565b50610128610526565b506101286104be565b50610128610343565b50610128610289565b600080fd5b6001600160a01b031690565b90565b6001600160a01b0381165b036101f357565b9050359061022682610207565b565b80610212565b9050359061022682610228565b608081830312610278575b6102508282610219565b926102046102618460208501610219565b9361026f816040860161022e565b9360600161022e565b610280600080fd5b610246565b9052565b506102b56102a461029b36600461023b565b9291909161126a565b6040515b9182918290815260200190565b0390f35b906102049160208183031215610219576102d1600080fd5b610219565b610204906101f8906001600160a01b031682565b610204906102d6565b610204906102ea565b90610306906102f3565b600052602052604060002090565b610204916008021c6101f8565b906102049154610314565b6102049061033e6006916000926102fc565b610321565b503461037a575b6102b561036061035b3660046102b9565b61032c565b604051918291826001600160a01b03909116815260200190565b610382600080fd5b61034a565b90916060828403126103b8575b6102046103a18484610219565b936103af8160208601610219565b9360400161022e565b6103c0600080fd5b610394565b50634e487b7160e01b600052602160045260246000fd5b600411156103e657565b6102266103c5565b90610226826103dc565b610204906103ee565b610285906103f8565b0190565b9061042e61042761041d845190565b8084529260200190565b9260200190565b9060005b81811061043f5750505090565b90919261046561045e60019286516001600160a01b0316815260200190565b9460200190565b929101610432565b610204916040606082019261048a60008201516000850190610401565b6020818101516001600160a01b031690840152015190604081840391015261040e565b60208082526102049291019061046d565b50346104e8575b6102b56104dc6104d6366004610387565b91612360565b604051918291826104ad565b6104f0600080fd5b6104c5565b919061020490604084820312610519575b6105108185610219565b93602001610219565b610521600080fd5b610506565b5034610546575b61054161053b3660046104f5565b90612317565b604051005b61054e600080fd5b61052d565b90610204916020818303121561022e5761056b600080fd5b61022e565b50634e487b7160e01b600052603260045260246000fd5b6105a7600191610595815490565b8410156105b057600052602060002090565b91020190600090565b6105b8610570565b600052602060002090565b600080548210156105e157610204916105db91610587565b90610321565b80fd5b5034610601575b6102b56103606105fc366004610553565b6105c3565b610609600080fd5b6105eb565b6102049061033e6008916000926102fc565b503461063d575b6102b56103606106383660046102b9565b61060e565b610645600080fd5b610627565b600091031261065557565b610226600080fd5b9061066c61042761041d845190565b9060005b81811061067d5750505090565b90919261069c61045e60019286516001600160a01b0316815260200190565b929101610670565b60208082526102049291019061065d565b50346106de575b6106c736600461064a565b6102b56106d2613a16565b604051918291826106a4565b6106e6600080fd5b6106bc565b5034610705575b6106fd36600461064a565b610541610da2565b61070d600080fd5b6106f2565b9091606082840312610743575b61020461072c8484610219565b9361073a8160208601610219565b93604001610219565b61074b600080fd5b61071f565b503461076e575b6102b56104dc610768366004610712565b916110b5565b610776600080fd5b610757565b50346107aa575b61078d36600461064a565b6102b5737f5c764cbc14f9669b88837ca1490cca17c31607610360565b6107b2600080fd5b610782565b601f01601f191690565b50634e487b7160e01b600052604160045260246000fd5b90601f01601f1916810190811067ffffffffffffffff8211176107fa57604052565b6108026107c1565b604052565b9061022661081460405190565b92836107d8565b6020809167ffffffffffffffff811161083357020190565b61083b6107c1565b020190565b909291926108556108508261081b565b610807565b9381855260208086019202830192818411610893575b915b83831061087a5750505050565b602080916108888486610219565b81520192019161086d565b61089b600080fd5b61086b565b906102049181601f820112156108bc575b602081359101610840565b6108c4600080fd5b6108b1565b90610204916020818303126108ff575b80359067ffffffffffffffff82116108f2575b016108a0565b6108fa600080fd5b6108ec565b610907600080fd5b6108d9565b5034610929575b6102b56106d26109243660046108c9565b613acf565b610931600080fd5b610913565b5034610953575b61094836600461064a565b6102b5610360610cea565b61095b600080fd5b61093d565b5034610981575b6102b56102a461097836600461023b565b92919091611e5b565b610989600080fd5b610967565b610204916008021c5b60ff1690565b90610204915461098e565b610204906109ba6001916000926102fc565b61099d565b50346109ee575b6102b56109dc6109d73660046102b9565b6109a8565b60405191829182901515815260200190565b6109f6600080fd5b6109c6565b5034610a1d575b610a0d36600461064a565b6102b56006602160991b01610360565b610a25600080fd5b610a02565b506102b56102a4610a3c36600461023b565b929190916116a1565b5034610a66575b6102b56102a4610a5d36600461023b565b92919091612081565b610a6e600080fd5b610a4c565b5034610a8e575b610541610a883660046104f5565b90612208565b610a96600080fd5b610a7a565b610204906109ba6007916000926102fc565b6020810192916102269190610401565b5034610ae6575b6102b5610ada610ad53660046102b9565b610a9b565b60405191829182610aad565b610aee600080fd5b610ac4565b5034610b0d575b610541610b083660046102b9565b612171565b610b15600080fd5b610afa565b5034610b34575b610541610b2f3660046102b9565b610e3e565b610b3c600080fd5b610b21565b608081830312610b91575b610b568282610219565b92610204610b678460208501610219565b93610b758160408601610219565b9360608101359067ffffffffffffffff82116108f257016108a0565b610b99600080fd5b610b4c565b5034610bbc575b610541610bb3366004610b41565b9291909161125e565b610bc4600080fd5b610ba5565b61040a60209167ffffffffffffffff8111610be857601f01601f191690565b6107b76107c1565b90610bfd61085083610bc9565b918252565b610c0c6001610bf0565b603360f81b602082015290565b610204610c02565b610204610c19565b610204610c21565b918091926000905b828210610c51575011610c4a575050565b6000910152565b91508060209183015181860152018291610c39565b610c876107b760209361040a93610c7b815190565b80835293849260200190565b95869101610c31565b602080825261020492910190610c66565b5034610cca575b610cb336600461064a565b6102b5610cbe610c29565b60405191829182610c90565b610cd2600080fd5b610ca8565b610204906101f8565b6102049054610cd7565b6102046005610ce0565b15610cfb57565b60405162461bcd60e51b815280610d44600482016020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b0390fd5b610d72610d53610cea565b610d6c610d5f336101f8565b916001600160a01b031690565b14610cf4565b610226610d90565b6101f86102046102049290565b61020490610d7a565b610226610d9d6000610d87565b610e77565b610226610d48565b61022690610db9610d53610cea565b610e19565b15610dc557565b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b61022690610d9d610e2d6101f86000610d87565b6001600160a01b0383161415610dbe565b61022690610daa565b906001600160a01b03905b9181191691161790565b90610e6c610204610e73926102f3565b8254610e47565b9055565b610e816005610ce0565b90610e8d816005610e5c565b610ec0610eba7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0936102f3565b916102f3565b91610eca60405190565b600090a3565b6102046060610807565b610ee2610ed0565b600080825260208201526060604082015290565b610204610eda565b610285906001600160a01b031660601b90565b60149392610f288583610f28829561040a97610efe565b018092610efe565b90610306565b6102046102046102049290565b61020490610997565b6102049054610f43565b90610285906103ee565b6102049060081c6101f8565b6102049054610f60565b90610f91610f8561041d845490565b92600052602060002090565b9060005b818110610fa25750505090565b909192610fcf610fc8600192610fb787610ce0565b6001600160a01b0316815260200190565b9460010190565b929101610f95565b9061020491610f76565b90610226610ffb92610ff260405190565b93848092610fd7565b03836107d8565b906102266110486001611013610ed0565b9461102661102082610f4c565b87610f56565b61104261103282610f6c565b6001600160a01b03166020880152565b01610fe1565b6040840152565b61020490611002565b90610bfd6108508361081b565b369037565b9061022661108061107a84611058565b9361081b565b601f190160208401611065565b906020809161109a845190565b8110156110a8575b02010190565b6110b0610570565b6110a2565b919290926110c1610ef6565b926110cb60405190565b6110eb81602081016110df868a8784610f11565b908103825203826107d8565b6110fd6110f6825190565b9160200190565b20906004956111166001611111858a610f30565b015490565b9260009361112a61112686610f36565b9190565b036112275750949550929361022693906006602160991b01806001600160a01b03841614158061120b575b156111d3576111aa906111976111bd9461118961118361117d6111786003610f36565b61106a565b98610f36565b8861108d565b906001600160a01b03169052565b6111896111a46001610f36565b8661108d565b6111896111b76002610f36565b8461108d565b60408501525b6001600160a01b03166020840152565b506111f4611201926111896111a46111ee6111786002610f36565b96610f36565b6111896111b76001610f36565b60408501526111c3565b506001600160a01b0381166001600160a01b0383161415611155565b9350505050610204925061123b9193610f30565b61104f565b90610226939291611252610d53610cea565b90610226939291613db2565b90610226939291611240565b92610226928261128493969561127e600090565b50612706565b61128e81946102f3565b33906112dc565b6112ae6112a86102049263ffffffff1690565b60e01b90565b6001600160e01b03191690565b6001600160a01b0390911681526040810192916102269160200152565b0152565b61131f600492611310610226956112f663a9059cbb611295565b9261130060405190565b96879460208601908152016112bb565b602082018103825203836107d8565b6113f0565b61132e6020610bf0565b7f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564602082015290565b610204611324565b801515610212565b905051906102268261135f565b9061020491602081830312156113675761138c600080fd5b611367565b1561139857565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b906113fd61140c926102f3565b90611406611357565b91611444565b805161141b6111266000610f36565b116114235750565b61143f816020611434610226945190565b818301019101611374565b611391565b61020492916114536000610f36565b9161151f565b1561146057565b60405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608490fd5b156114bb57565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b3d1561151a5761150f3d610bf0565b903d6000602084013e565b606090565b6102049392600092839291611540611536306102f3565b8290311015611459565b61155161154c84611568565b6114b4565b602082019151925af1611562611500565b9061157a565b3b6115766111266000610f36565b1190565b90919015611586575090565b81516115956111266000610f36565b11156115a45750805190602001fd5b610d44906115b160405190565b62461bcd60e51b815291829160048301610c90565b9050519061022682610207565b9061020491602081830312156115c6576115eb600080fd5b6115c6565b506040513d6000823e3d90fd5b9050519061022682610228565b9061020491602081830312156115fd57611622600080fd5b6115fd565b50634e487b7160e01b600052601160045260246000fd5b818110611649570390565b611651611627565b0390565b1561165c57565b60405162461bcd60e51b815260206004820152601760248201527f6465706f7369742d696e2d7661756c742d6661696c65640000000000000000006044820152606490fd5b919093926116ad600090565b506116bf6116ba866102f3565b6102f3565b631f1fcd51906116d86116d160405190565b9260e01b90565b8252602082600481845afa918215611cab575b600092611c89575b5081926117056116ba611749946102f3565b630dfe1681906117176116d160405190565b8252602082600481845afa918215611c7c575b600092611c5a575b5060405160209163d21220a7915b96879260e01b90565b825260049082905afa938415611c4d575b600094611c19575b5061176c906102f3565b91611776836102f3565b90611780306102f3565b9061178a60405190565b6370a0823160e01b81526001600160a01b038316600482015295602087602481875afa968715611c0c575b600097611be8575b506117c7906102f3565b966117d1886102f3565b946117db60405190565b6370a0823160e01b81526001600160a01b03851660048201529960208b6024818a5afa9a8b15611bdb575b60009b611bad575b509061182091836119f29b9c9d612706565b9161192560206118f4859f61183460405190565b6370a0823160e01b81526001600160a01b03891660048201528784826024818a5afa918215611ba0575b600092611b7f575b5061187a9192611875896102f3565b611d4d565b63b6b55f25853b15611b72575b61189a61189360405190565b9160e01b90565b815260048101889052600081602481838a5af18015611b65575b611b3f575b506040516370a0823160e01b81526001600160a01b03891660048201528381602481895afa908115611b32575b600091611b15575b5061163e565b6119086119016000610f36565b8211611655565b60405192839182919063a9059cbb60e01b835233600484016112bb565b03816000865af18015611b08575b611adc575b507ffb4595efc62c0b8b1567ac9769b05ea4215e28a83691f58ba050aa6981c7c3cb61197c61197261196c61196c336102f3565b946102f3565b946102a860405190565b0390a4602061198a60405190565b6370a0823160e01b81526001600160a01b038316600482015292839060249082905afa918215611acf575b600092611aaf575b50602091926119cb60405190565b968792839182916370a0823160e01b5b83526001600160a01b031660048301526024820190565b03915afa938415611aa2575b600094611a72575b50611a11838261163e565b611a1e6111266000610f36565b11611a5d575b505050611a31838261163e565b611a3e6111266000610f36565b11611a4857505050565b61022692611a559161163e565b9033906112dc565b611a6a92611a559161163e565b388080611a24565b611a9491945060203d8111611a9b575b611a8c81836107d8565b81019061160a565b9238611a06565b503d611a82565b611aaa6115f0565b6119fe565b60209250611ac990833d8111611a9b57611a8c81836107d8565b916119bd565b611ad76115f0565b6119b5565b611afc9060203d8111611b01575b611af481836107d8565b810190611374565b611938565b503d611aea565b611b106115f0565b611933565b611b2c9150843d8111611a9b57611a8c81836107d8565b386118ee565b611b3a6115f0565b6118e6565b611b589060005b611b5081836107d8565b81019061064a565b386118b9565b503d611b46565b611b6d6115f0565b6118b4565b611b7a600080fd5b611887565b61187a9250611b9a90863d8111611a9b57611a8c81836107d8565b91611866565b611ba86115f0565b61185e565b6119f29a9b509083611bd0611820949360203d8111611a9b57611a8c81836107d8565b9c9b5050909161180e565b611be36115f0565b611806565b6117c7919750611c059060203d8111611a9b57611a8c81836107d8565b96906117bd565b611c146115f0565b6117b5565b61176c919450611c3f9060203d8111611c46575b611c3781836107d8565b8101906115d3565b9390611762565b503d611c2d565b611c556115f0565b61175a565b6020919250611c7590823d8111611c4657611c3781836107d8565b9190611732565b611c846115f0565b61172a565b6117499250611ca59060203d8111611c4657611c3781836107d8565b916116f3565b611cb36115f0565b6116eb565b6001600160a01b039091168152604081019291610226916020905b01906001600160a01b03169052565b15611ce957565b60405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608490fd5b61131f60049261131061022695611d7a600084611d6982610f36565b8414918215611d87575b5050611ce2565b6112f663095ea7b3611295565b9091506020611d95896102f3565b63dd62ed3e90611dc1611da7306102f3565b92611dcc611db460405190565b9788958694859460e01b90565b845260048401611cb8565b03915afa918215611e1d575b600092611df5575b50611126611ded91610f36565b148438611d73565b611ded919250611e156111269160203d8111611a9b57611a8c81836107d8565b929150611de0565b611e256115f0565b611dd8565b6001600160a01b0390911681526060810193926102269290916040916112d8905b6001600160a01b03166020830152565b6116ba611e749195949395611e6e600090565b506102f3565b91631f1fcd5190611e876116d160405190565b8252602082600481875afa918215612074575b60009261204e575b50611f73611f8e9293602060006323b872dd99339a838c8b611ee3611ec6306102f3565b968795611eee88611ed660405190565b9889978896879560e01b90565b855260048501611e2a565b03925af18015612041575b612026575b506000611f28632e1a7d4d8b3b15612019575b611f36611f1d60405190565b948593849360e01b90565b835260048301526024820190565b0381838d5af1801561200c575b611ff6575b50611f556116ba886102f3565b6119db6370a08231611f6660405190565b9687948593849360e01b90565b03915afa918215611fe9575b600092611fc9575b50846132fd565b918294611fc461197261196c61196c7fb6b31433b0feeb179e7bdaf74af8f681471ac78f86bddc6e35ab7f514f84af03946102f3565b0390a4565b611fe291925060203d8111611a9b57611a8c81836107d8565b9038611f87565b611ff16115f0565b611f7f565b612006906000611b5081836107d8565b38611f48565b6120146115f0565b611f43565b612021600080fd5b611f11565b61203c90843d8111611b0157611af481836107d8565b611efe565b6120496115f0565b611ef9565b611f8e925061206d611f739160203d8111611c4657611c3781836107d8565b9250611ea2565b61207c6115f0565b611e9a565b610204939291906120a583612095836102f3565b3361209f306102f3565b916120aa565b6132fd565b9061131f90611310610226956004956120c66323b872dd611295565b936120d060405190565b9788956020870190815201611e2a565b610226906120ef610d53610cea565b61212a610226916120ff816102f3565b6020339261210c836102f3565b6119db6370a0823161211d60405190565b9788948593849360e01b90565b03915afa928315612164575b600093612144575b506112dc565b61215d91935060203d8111611a9b57611a8c81836107d8565b913861213e565b61216c6115f0565b612136565b610226906120e0565b906102269161218a610d53610cea565b6121c9565b1561219657565b60405162461bcd60e51b815260206004820152600b60248201526a185b1c9958591e4b5cd95d60aa1b6044820152606490fd5b906122036102269260086121fe6121e86121e384846102fc565b610ce0565b6121f8610d5f6101f86000610d87565b1461218f565b6102fc565b610e5c565b906102269161217a565b9061022691612222610d53610cea565b61223f565b6001906000198114612237570190565b61040a611627565b9160009161224c83610f36565b612257610204855490565b8110156123065761226b6105db8286610587565b61227d6001600160a01b038416610d5f565b146122f2576122a0610204612290865490565b61229a6001610f36565b9061163e565b81146122b4576122af90612227565b61224c565b60405162461bcd60e51b81526020600482015260166024820152751c9bdd5d195c8b5b9bdd0b5dda1a5d195b1a5cdd195960521b6044820152606490fd5b5090926102269250612203905b60066102fc565b5090926102269250612203906122ff565b9061022691612212565b61020490610fe1565b1561233157565b60405162461bcd60e51b81526020600482015260076024820152660dcde5ae0c2e8d60cb1b6044820152606490fd5b909261236a610ef6565b9260009061237782612321565b9561238183610f36565b93845b61238f6102048a5190565b81101561257f576123b06123a3828b61108d565b516001600160a01b031690565b6123bb81858a6110b5565b906123cf6123ca8260076102fc565b610f4c565b916123db838883614be1565b898111612573575b5089929190506006602160991b01806001600160a01b03851614159081612556575b506124e0575b87737f5c764cbc14f9669b88837ca1490cca17c31607806001600160a01b0386161415806124c4575b61244c575b505050505061244790612227565b612384565b9161249e916124786124a595946111f4612464610ef6565b986111896111a46111ee6111786003610f36565b612489896111896111b76002610f36565b60408601526001600160a01b03166020850152565b8683614be1565b8781116124b6575b80878a93612439565b9098509550612447386124ad565b506001600160a01b0381166001600160a01b0389161415612434565b9091506124eb610ef6565b6124f86111786002610f36565b6125088b6111896111b78c610f36565b612519876111896111b76001610f36565b60408201526001600160a01b0382166020820152612538838883614be1565b89811161254a575b505090889161240b565b909a5097508838612540565b6001600160a01b031690506001600160a01b038716141538612405565b909a50975088386123e3565b5096505050610204925061112661259591610f36565b1161232a565b156125a257565b60405162461bcd60e51b815260206004820152601260248201527134b73b30b634b216b33937b696ba37b5b2b760711b6044820152606490fd5b156125e357565b60405162461bcd60e51b815260206004820152601160248201527034b73b30b634b216b0b6b7bab73a16b4b760791b6044820152606490fd5b50634e487b7160e01b600052601260045260246000fd5b811561263d570490565b61264561261c565b0490565b806000190482118115151661265c570290565b612664611627565b0290565b60ff8116610212565b9050519061022682612668565b90610204916020818303121561267157612696600080fd5b612671565b60ff16604d81116126ad575b600a0a90565b6126b5611627565b6126a7565b81198111612237570190565b156126cd57565b60405162461bcd60e51b8152602060048201526011602482015270736c6970706167652d72656b742d796f7560781b6044820152606490fd5b929392916000916000913461271a84610f36565b811115612ed0578361276e6127526116ba6006602160991b01612747816001600160a01b038d161461259b565b6116ba8688146125dc565b63d0e30db0813b15612ec3575b6040515b948593849260e01b90565b82526004925af18015612eb6575b612e9a575b505b61278c82612f24565b94859361279b6116ba856102f3565b90630dfe1681946127b56127ae60405190565b9660e01b90565b8652602086600481865afa958615612e8d575b600096612e6d575b5063d21220a7976127ea6127e360405190565b9960e01b90565b8952602089600481875afa988915612e60575b600099612e32575b50918791878a96959460029561282d61282661282089610f36565b8c612633565b848a612360565b61285361284c6128468d6128408c610f36565b90612633565b8d61163e565b8b8b612360565b92508986996007936128686123ca8b876102fc565b9060019161287e612878846103ee565b916103ee565b148c8c8215612e0e575b5050612da8575b508d8c612a8057505050506128a388610f36565b6128ad908c612633565b60208201516001600160a01b03166128c590846102fc565b6128ce90610f4c565b906128d8926140ea565b996128e38b98610f36565b6128ed9082612633565b6128f69161163e565b9061290b60208401516001600160a01b031690565b612914916102fc565b61291d90610f4c565b90612927926140ea565b6102269c6129fe9c611875839861296b986116ba986118756129636129576129516116ba9b6102f3565b93610f36565b966116ba888686611d4d565b958387611d4d565b936370a082319361297b306102f3565b9661298560405190565b986129908760e01b90565b8a526001600160a01b03891660048b015260208a6024818b5afa998a15612a73575b60009a612a35575b50936129e59896936129d49360209997936119db97613131565b6040515b9586948593849360e01b90565b03915afa908115612a28575b600091612a10575061163e565b612a09611126829590565b10156126c6565b611b2c915060203d8111611a9b57611a8c81836107d8565b612a306115f0565b6129f1565b6119db95919a50936129d4936020999793612a616129e59c9a978c3d8111611a9b57611a8c81836107d8565b9c9397509397995093509396986129ba565b612a7b6115f0565b6129b2565b91888b879d9387878b8b8e998a612ab0612b6c9d9e9f9b612aa3612aa991610f36565b84612633565b809361163e565b956001600160a01b038b166001600160a01b03831614612d9757612b3e6020612b266116ba612b20612b0986612b5d99612b036123ca8d612afd8a6128409d01516001600160a01b031690565b906102fc565b91614be1565b612b1a670de0b6b3a7640000610f36565b90612649565b956102f3565b63313ce56790612b3560405190565b93849260e01b90565b825260049082905afa908115612d5b575b600091612d2d575b5061269b565b9a8b986001600160a01b031690565b6001600160a01b03841614612d8c576020612b266116ba612b20612b0986612bae99612b036123ca612b3e99612afd8a6128409d01516001600160a01b031690565b9788955b83612bbc916102fc565b612bc590610f4c565b96612bcf97614f21565b509190928c670de0b6b3a764000094612be786610f36565b612bf091612649565b612bf9896102f3565b612c02906102f3565b63313ce56790612c1160405190565b90612c1c8360e01b90565b8252816004815a93602094fa9182156116ba612c62612c58612c7097612840612b3e98602098612c6897612d7f575b600091612d68575061269b565b9a612b1a8d610f36565b966102f3565b604051612b35565b612c7991612633565b91612c8385610f36565b612c8c91612649565b90612c9691612633565b90612ca091612649565b90612caa91612633565b612cb382610f36565b612cbd908d612649565b91612cc790610f36565b612cd0916126ba565b612cd991612633565b998a612ce49161163e565b99612cf960208301516001600160a01b031690565b612d0390896102fc565b612d0c90610f4c565b90612d16926140ea565b98899661290b60208401516001600160a01b031690565b612d4e915060203d8111612d54575b612d4681836107d8565b81019061267e565b38612b57565b503d612d3c565b612d636115f0565b612b4f565b612d4e9150893d8111612d5457612d4681836107d8565b612d876115f0565b612c4b565b505050978895612bb2565b50509a8b986001600160a01b031690565b612dc0919c506020906322be3de190612b3560405190565b825260049082908d905af1908115612e01575b600091612de3575b509a3861288f565b612dfb915060203d8111611b0157611af481836107d8565b38612ddb565b612e096115f0565b612dd3565b612e2a919250612e246123ca612878928b6102fc565b926103ee565b148c8c612888565b87995091612e538993602097969593973d8111611c4657611c3781836107d8565b9950919490929394612805565b612e686115f0565b6127fd565b612e8691965060203d8111611c4657611c3781836107d8565b94386127d0565b612e956115f0565b6127c8565b612eb090843d8611611b5e57611b5081836107d8565b38612781565b612ebe6115f0565b61277c565b612ecb600080fd5b61275f565b50612ede81612095876102f3565b612783565b15612eea57565b60405162461bcd60e51b81526020600482015260126024820152713ab739bab83837b93a32b216b937baba32b960711b6044820152606490fd5b600690612f346121e382846102fc565b91612f3f6000610d87565b92612f526001600160a01b038516610d5f565b03612ffc5750612f88610204926020612f706116ba6121e3956102f3565b63c45a015590612f7f60405190565b94859260e01b90565b825260049082905afa918215612fef575b600092612fcf575b506121fe600891612fc8610d5f612fbb6121e387876102fc565b926001600160a01b031690565b1415612ee3565b612fe891925060203d8111611c4657611c3781836107d8565b9038612fa1565b612ff76115f0565b612f99565b6102049250906121e3916102fc565b909160608284031261303c575b61020461302584846115fd565b9361303381602086016115fd565b936040016115fd565b613044600080fd5b613018565b61028590610f36565b9694929099989795939161012088019a60008901613077916001600160a01b03169052565b6001600160a01b03166020880152151560408701526060860152608085015260a084016130a391613049565b60c083016130b091613049565b6001600160a01b031660e08201526101000152565b95939198979694929098610100870199600088016130ea916001600160a01b03169052565b6001600160a01b0316602087015260408601525b60608501526080840161311091613049565b60a0830161311d91613049565b6001600160a01b031660c082015260e00152565b9394909291946131456123ca8660076102fc565b91600092613152846103ee565b61315b826103ee565b036131f9575050906131a3916131ae6131786116ba6060986102f3565b9463e8e3370092848061318a306102f3565b92429461319660405190565b9d8e9c8d9b8c9a60e01b90565b8a5260048a016130c5565b03925af180156131ec575b6131c05750565b6131e09060603d81116131e5575b6131d881836107d8565b81019061300b565b505050565b503d6131ce565b6131f46115f0565b6131b9565b6132076001949392946103ee565b613210826103ee565b149081156132a5575b501561326a576131ae61325f936132346116ba6060996102f3565b958480635a47ddc395613246306102f3565b93429561325260405190565b9e8f9d8e9c8d9b60e01b90565b8b5260048b01613052565b60405162461bcd60e51b8152602060048201526013602482015272696e76616c69642d726f757465722d7479706560681b6044820152606490fd5b90506132b461287860026103ee565b1438613219565b156132c257565b60405162461bcd60e51b8152602060048201526013602482015272199d1b4b5d1c985b9cd9995c8b59985a5b1959606a1b6044820152606490fd5b906133b491819395949561330f600090565b5061331982612f24565b916133266116ba826102f3565b90630dfe16819261334061333960405190565b9460e01b90565b8452602084600481865afa938415613805575b6000946137e3575b50613528939463d21220a79161337a61337360405190565b9360e01b90565b8352602083600481885afa9283156137d6575b6000936137a8575b506133bb81836133a86133f196976102f3565b61187560009d8e610f36565b8383611d4d565b83878a938b6007986133d06123ca848c6102fc565b6133dd61287860016103ee565b148015613787575b613724575b50506138e5565b6133fd6116ba856102f3565b916134f461344e6370a0823196613413306102f3565b9a8b9160206119db8b61343361342860405190565b968793849360e01b90565b03818b5afa928315613717575b6000936136f7575b50612360565b916134da61348f8b8a6134636116ba896102f3565b9760206119db8d61347661342860405190565b03818c5afa928315613717576000936136f75750612360565b9360208c6134cc6123ca6134b86123ca6134b2868801516001600160a01b031690565b896102fc565b96612afd858b01516001600160a01b031690565b986119db8c611f6660405190565b03915afa9182156136ea575b6000926136ca575b506140ea565b50602061350060405190565b809361350c8860e01b90565b82526001600160a01b038b1660048301528180602481016134da565b5060206119db61353a6116ba856102f3565b9261355261354760405190565b978893849360e01b90565b0381845afa9384156136bd575b60009461369d575b50613579613573859790565b85612a09565b6006602160991b019161358b83610d5f565b036136305750610226926135bb836135a66116ba82956102f3565b632e1a7d4d90803b1561362357604051612b35565b825260048201859052602490829084905af18015613616575b6135fa575b5033906135e560405190565b90818003925af16135f4611500565b506132bb565b61361090833d8511611b5e57611b5081836107d8565b386135d9565b61361e6115f0565b6135d4565b61362b600080fd5b612c68565b602092915061365963a9059cbb92339361366461364c60405190565b9788968795869460e01b90565b8452600484016112bb565b03925af18015613690575b6136765750565b61368d9060203d8111611b0157611af481836107d8565b50565b6136986115f0565b61366f565b6136b691945060203d8111611a9b57611a8c81836107d8565b9238613567565b6136c56115f0565b61355f565b6136e391925060203d8111611a9b57611a8c81836107d8565b90386134ee565b6136f26115f0565b6134e6565b61371091935060203d8111611a9b57611a8c81836107d8565b9138613448565b61371f6115f0565b613440565b60209192965061373c906322be3de161276360405190565b82526004925af190811561377a575b60009161375c575b50938b386133ea565b613774915060203d8111611b0157611af481836107d8565b38613753565b6137826115f0565b61374b565b506137956123ca848c6102fc565b6137a261287860026103ee565b146133e5565b6133f1935081836133a86137cc6133bb9460203d8111611c4657611c3781836107d8565b9650505050613395565b6137de6115f0565b61338d565b61352894506137ff9060203d8111611c4657611c3781836107d8565b9361335b565b61380d6115f0565b613353565b919061020490604084820312613836575b61382d81856115fd565b936020016115fd565b61383e600080fd5b613823565b9593919897969492909861010087019960008801613868916001600160a01b03169052565b6001600160a01b03166020870152151560408601526130fe565b949290979695939160e0860198600087016138a4916001600160a01b03169052565b6001600160a01b031660208601526040850152606084016138c491613049565b608083016138d191613049565b6001600160a01b031660a082015260c00152565b939091936138f76123ca8260076102fc565b91600092613904846103ee565b61390d826103ee565b036139a9575050604093916139276116ba613954936102f3565b9261395f63baa2abde9161393a306102f3565b8480429361394760405190565b9c8d9b8c9a8b9960e01b90565b895260048901613882565b03925af1801561399c575b6139715750565b6139919060403d8111613995575b61398981836107d8565b810190613812565b5050565b503d61397f565b6139a46115f0565b61396a565b6139b660019492946103ee565b6139bf826103ee565b14908115613a00575b501561326a5760409461395f6139e36116ba6139f5956102f3565b94630dede6c492848061318a306102f3565b8a5260048a01613843565b9050613a0f61287860026103ee565b14386139c8565b6102046060613a256002613aad565b905090565b6102049081565b6102049054613a2a565b90613a4a610f8561041d845490565b9060005b818110613a5b5750505090565b909192613a78610fc8600192613a7087613a31565b815260200190565b929101613a4e565b9061020491613a3b565b90610226610ffb92613a9b60405190565b93848092613a80565b61020490613a8a565b600061020491613abb606090565b5001613aa4565b6001908015611649570390565b90815191613adc8361106a565b90613ae76000610f36565b6001613af281610f36565b8610613b3b57613b3591613b2a613b206123a3613b1a613b14613b2f96610f36565b8b61163e565b8761108d565b611189838861108d565b612227565b94613ac2565b93613ae7565b509193505050565b15613b4a57565b60405162461bcd60e51b815260206004820152600c60248201526b0d2dcecc2d8d2c85ae0c2e8d60a31b6044820152606490fd5b15613b8557565b60405162461bcd60e51b815260206004820152600e60248201526d34b73b30b634b216b937baba32b960911b6044820152606490fd5b61020490516103ee565b9060ff90610e52565b90613bde610204610e73926103f8565b8254613bc5565b90610100600160a81b039060081b610e52565b90613c08610204610e73926102f3565b8254613be5565b9160001960089290920291821b911b610e52565b9190613c34610204610e7393610f36565b908354613c0f565b61022691600091613c23565b818110613c53575050565b80613c616000600193613c3c565b01613c48565b9091828110613c7557505050565b6102269290613c8390610f85565b9081019101613c48565b9061022691680100000000000000008211613cae575b805490828155613c67565b613cb66107c1565b613ca3565b916001600160a01b0360089290920291821b911b610e52565b9190613ce5610204610e73936102f3565b908354613cbb565b613d18613d0c613cfb845190565b93613d068585613c8d565b60200190565b91600052602060002090565b600080925b848410613d2b575050505050565b6001602082613d4c613d458495516001600160a01b031690565b8688613cd4565b01930193019291613d1d565b9061022691613ced565b6102269190613da290604090600190613d9b81613d87613d8188613bbb565b82613bce565b60208701516001600160a01b031690613bf8565b0192015190565b90613d58565b9061022691613d62565b92613eca91613eeb84613ee4613ecf613dde97613e806102269a613dfc613de46123a360009d8e610f36565b8c61108d565b613df66001600160a01b038416610d5f565b14613b43565b613e22613e106123a3613dde6122908d5190565b613df66001600160a01b038b16610d5f565b613e42613e316101f88d610d87565b6001600160a01b0385161415613b7e565b604051613e5981602081016110df878d8784610f11565b613e646110f6825190565b20976110df613e7260405190565b948593602085019384610f11565b613e8b6110f6825190565b2095610924613e98610ed0565b613ea48b808301610f56565b6001600160a01b0386166020820152613ebe836040830152565b613eca60049889610f30565b613da8565b91611032613edb610ed0565b98808a01610f56565b6040860152565b610f30565b90613eff61042761041d845190565b9060005b818110613f105750505090565b909192613f5661045e600192865180516001600160a01b039081168352602080830151821690840152604080830151151590840152606091820151169082015260800190565b929101613f03565b90613f996112d89161022696989795613f8c608096613f8260a08801946000890152565b6020870190613049565b8482036040860152613ef0565b6001600160a01b039097166060830152565b80516001600160a01b03168252610226919060409081906020818101516001600160a01b03169085015201511515910152565b9061040a81606093613fab565b90613ffa61042761041d845190565b9060005b81811061400b5750505090565b90919261401e61045e6001928651613fde565b929101613ffe565b90613f996112d8916102269698979561404a608096613f8260a08801946000890152565b8482036040860152613feb565b91946140a96140976112d89360a09661408a6102269a9c9b999c61408060c08a019460008b0152565b6020890190613049565b868203604088015261065d565b6001600160a01b039099166060850152565b6001600160a01b03166080830152565b90613f996112d891610226969897956140dd608096613f8260a08801946000890152565b848203604086015261065d565b909190604081019283519361410d6123a360009661410788610f36565b9061108d565b948151956141306123a361412085515190565b9861410760019a61229a8c610f36565b906001600160a01b0382166001600160a01b038216146144a857614199916116ba602061415f6116ba946102f3565b9801976141866141768a516001600160a01b031690565b61417f88610f36565b9083611d4d565b88516001600160a01b0316861991611d4d565b926370a08231926141a9306102f3565b956141b360405190565b976141be8660e01b90565b89526001600160a01b03881660048a01526020896024818a5afa98891561449b575b60009961447b575b506141f2856103ee565b6141fb826103ee565b036142b257509261020498816119db946129e59997946142568361422f6116ba6116ba60209e9c516001600160a01b031690565b92614261635c11d79591518d4291873b156142a5575b6040515b9a8b998a98899760e01b90565b8752600487016140b9565b03925af18015614298575b61427b575b50506040516129d8565b8161429192903d10611b5e57611b5081836107d8565b3880614271565b6142a06115f0565b61426c565b6142ad600080fd5b614245565b6142bc60036103ee565b6142c5826103ee565b0361437957509261020498816119db946129e5999794614320836142f96116ba6116ba60209e9c516001600160a01b031690565b9261432b63ac3893ba91518d804292883b1561436c575b6040519b8c9a8b998a9860e01b90565b885260048801614057565b03925af1801561435f575b614342575b50506129d4565b8161435892903d10611b5e57611b5081836107d8565b388061433b565b6143676115f0565b614336565b614374600080fd5b614310565b6143828a6103ee565b61438b826103ee565b0361440457509261020498816119db946129e59997946143f9838961432b6143e76143c760209f9d6116ba6116ba91516001600160a01b031690565b956143de636cc1ae1394516001600160a01b031690565b90519088614568565b8d4291873b156142a557604051614249565b875260048701614026565b614419612878600299979495989693996103ee565b0361326a5761020498816020976119db95614470838c61432b6143e76129e59f6116ba6116ba61445092516001600160a01b031690565b956144676388cd821e94516001600160a01b031690565b90519088614765565b875260048701613f5e565b61449491995060203d8111611a9b57611a8c81836107d8565b97386141e8565b6144a36115f0565b6141e0565b505050509250505090565b6144bb610ed0565b906000825260208080840160005b8152016000905250565b6102046144b3565b60005b8281106144ea57505050565b6020906144f56144d3565b81840152016144de565b9061022661450f61107a84611058565b601f1901602084016144db565b919061020490604084820312614540575b61453781856115fd565b93602001611367565b614548600080fd5b61452d565b908152606081019392610226929091604091611cd390611e4b565b909161458291815190614587600194859361229a85610f36565b6144ff565b946000925b614599575b505050505090565b6145b06102046145a7865190565b61229a88610f36565b8310156146ed576146a985604081946145cb6116ba866102f3565b61460b635e1e63256146166145fb6123a38d6141078e6145f56145ef85838661108d565b9c610f36565b906126ba565b6040519788968795869560e01b90565b85526004850161454d565b03915afa9081156146e0575b6000809190926146b0575b5061468d61463e6123a3888a61108d565b9161468461465a6123a3613dde6146548b610f36565b8c6126ba565b614674614665610ed0565b6001600160a01b039096168652565b6001600160a01b03166020850152565b15156040830152565b614697868a61108d565b526146a2858961108d565b5093612227565b929161458c565b90506146d3915060403d81116146d9575b6146cb81836107d8565b81019061451c565b3861462d565b503d6146c1565b6146e86115f0565b614622565b614591565b6102046080610807565b6147046146f2565b906000825260208080808501600081520160006144c9565b6102046146fc565b60005b82811061473357505050565b60209061473e61471c565b8184015201614727565b9061022661475861107a84611058565b601f190160208401614724565b6147869260206147776116ba856102f3565b63d4b6846d9061174060405190565b825260049082905afa938415614a2c575b600094614a06575b5090816147ad6147bf935190565b916147c4600194859461229a86610f36565b614748565b956000935b6147d7575b50505050505090565b6147e56102046145a7855190565b841015614a015784916147f783610f36565b61480081614748565b9061480b878761108d565b516001600160a01b031661481f82896126ba565b614829908861108d565b516001600160a01b031661483b6146f2565b6001600160a01b0390921682526001600160a01b0316602082015285151560408201526001600160a01b038516606082015260009061487982610f36565b614883908561108d565b5261488d81610f36565b614897908461108d565b506148a182614748565b926148ac898961108d565b516001600160a01b03166148c0848b6126ba565b6148ca908a61108d565b516001600160a01b03166148dc6146f2565b6001600160a01b03909216848301526001600160a01b0316602082015282151560408201526001600160a01b038716606082015261491983610f36565b614923908661108d565b5261492d82610f36565b614937908561108d565b5061494390858c614b18565b938493614950918c614b18565b9384109161495e898961108d565b516001600160a01b031690614973908a6126ba565b61497d908961108d565b516001600160a01b0316906149906146f2565b928301906149a691906001600160a01b03169052565b6001600160a01b0316602082015281151560408201526001600160a01b03851660608201526149d5888c61108d565b526149e0878b61108d565b506149f29290156149f9575094612227565b93916147c9565b905094612227565b6147ce565b6147bf92919450614a249060203d8111611c4657611c3781836107d8565b93909161479f565b614a346115f0565b614797565b90929192614a496108508261081b565b9381855260208086019202830192818411614a87575b915b838310614a6e5750505050565b60208091614a7c84866115fd565b815201920191614a61565b614a8f600080fd5b614a5f565b906102049181601f82011215614ab0575b602081519101614a39565b614ab8600080fd5b614aa5565b9061020491602081830312614af3575b80519067ffffffffffffffff8211614ae6575b01614a94565b614aee600080fd5b614ae0565b614afb600080fd5b614acd565b90815260406020820181905261020492910190613ef0565b929190600090614b2a6116ba83612c62565b614b4b635509a1ac614b56614b3e60405190565b9687958694859460e01b90565b845260048401614b00565b03915afa60009181614b8e575b50614b75575090506102046000610f36565b61020491925080614107612290614b8a935190565b5190565b614baa91923d8091833e614ba281836107d8565b810190614abd565b9038614b63565b9081526040602082018190526102049291019061065d565b90815260406020820181905261020492910190613feb565b91906040830190815193614bfd6123a360009661410788610f36565b93835194614c26610d5f6101f86123a3614c1689515190565b9961410760019b61229a8d610f36565b14614e6657614c34866103ee565b614c3d826103ee565b14614de5575b614c4c856103ee565b614c55826103ee565b14614d2d575b614c6861287860026103ee565b14614c7b575b5050505061020490610f36565b90614cb66116ba6116ba614ca8602089960196614c9f88516001600160a01b031690565b90519086614765565b95516001600160a01b031690565b614b4b635509a1ac614cca614b3e60405190565b03915afa60009181614d12575b50614cf55750614cec57610204388080614c6e565b61020490610f36565b6102049250614107614b8a9261229a614d0c845190565b91610f36565b614d2691923d8091833e614ba281836107d8565b9038614cd7565b614d868660208401614d696116ba6116ba614d5b614d5285516001600160a01b031690565b8b51908b614568565b93516001600160a01b031690565b614d7a639881fcb46129d860405190565b83528a60048401614bc9565b03915afa60009181614dc9575b50614dad57508415614c5b57505050505061020490610f36565b93505050506102049250614107614b8a9261229a614d0c845190565b614dde9192503d808a833e614ba281836107d8565b9038614d93565b614e2486614e036116ba6116ba60208701516001600160a01b031690565b63d06ca61f90614e188851926129d860405190565b83528a60048401614bb1565b03915afa60009181614e4b575b50614dad57508415614c4357505050505061020490610f36565b614e5f91923d8091833e614ba281836107d8565b9038614e31565b50509250505090565b9095949261022694614eb76112d892614eae608096614e9e60a088019c60008901906001600160a01b03169052565b6001600160a01b03166020870152565b15156040850152565b6060830152565b9194614f1a6112d892989795614f0a60a096614f016102269a614ef160c08a019e60008b01906001600160a01b03169052565b6001600160a01b03166020890152565b15156040870152565b6001600160a01b03166060850152565b6080830152565b959697949092919397614f32600090565b9788998998614f4160016103ee565b614f4a826103ee565b1461505a575b614f5d61287860026103ee565b14614f6c575b50505050505050565b614fcc95979a50614fd7939496995060609850614f8e6116ba614fa2926102f3565b966020612f706116ba63ce700c29986102f3565b825260049082905afa91821561504d575b60009261502d575b506040519a8b998a98899860e01b90565b885260048801614ebe565b03915afa8015615020575b6000808091939092614fff575b5090919238808080808080614f63565b91505061501a915060603d81116131e5576131d881836107d8565b38614fef565b6150286115f0565b614fe2565b61504691925060203d8111611c4657611c3781836107d8565b9038614fbb565b6150556115f0565b614fb3565b9a5061506a9199508098506102f3565b615073906102f3565b976398a0fb3c9861508360405190565b9960e01b8a52898061509c8585898c8c60048701614e6f565b03815a93606094fa9788156150eb575b60008080919b909a6150c2575b5098999a614f50565b919950506150df91995060603d81116131e5576131d881836107d8565b389a929a9991996150b9565b6150f36115f0565b6150ac56fea2646970667358221220421276f12fe068ca0f7c2f7975947bc8f6a9003b7aee217fb0a2d2739582f68c64736f6c634300080e0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 32 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.