Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 22,034 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Multicall | 18925031 | 359 days ago | IN | 0 ETH | 0.00308718 | ||||
Multicall | 18909549 | 361 days ago | IN | 0 ETH | 0.00479247 | ||||
Multicall | 18899631 | 363 days ago | IN | 0 ETH | 0.01566076 | ||||
Multicall | 18899321 | 363 days ago | IN | 0 ETH | 0.0130652 | ||||
Multicall | 18897936 | 363 days ago | IN | 0 ETH | 0.00612967 | ||||
Multicall | 18889298 | 364 days ago | IN | 0 ETH | 0.00436714 | ||||
Multicall | 18882986 | 365 days ago | IN | 0 ETH | 0.01096057 | ||||
Multicall | 18882938 | 365 days ago | IN | 0 ETH | 0.01195019 | ||||
Multicall | 18882915 | 365 days ago | IN | 0 ETH | 0.00523678 | ||||
Multicall | 18882911 | 365 days ago | IN | 0 ETH | 0.00692019 | ||||
Multicall | 18882765 | 365 days ago | IN | 0 ETH | 0.00537091 | ||||
Multicall | 18882111 | 365 days ago | IN | 0 ETH | 0.01212702 | ||||
Multicall | 18881922 | 365 days ago | IN | 0 ETH | 0.00926656 | ||||
Multicall | 18881896 | 365 days ago | IN | 0 ETH | 0.00798386 | ||||
Multicall | 18881700 | 365 days ago | IN | 0 ETH | 0.02028033 | ||||
Multicall | 18881487 | 365 days ago | IN | 0 ETH | 0.00493899 | ||||
Multicall | 18881380 | 365 days ago | IN | 0 ETH | 0.0112001 | ||||
Multicall | 18881244 | 365 days ago | IN | 0 ETH | 0.00942809 | ||||
Multicall | 18881220 | 365 days ago | IN | 0 ETH | 0.00494272 | ||||
Multicall | 18880999 | 365 days ago | IN | 0 ETH | 0.00713915 | ||||
Multicall | 18880893 | 365 days ago | IN | 0 ETH | 0.00944473 | ||||
Multicall | 18880806 | 365 days ago | IN | 0 ETH | 0.01270698 | ||||
Multicall | 18880787 | 365 days ago | IN | 0 ETH | 0.00493179 | ||||
Multicall | 18880574 | 365 days ago | IN | 0 ETH | 0.0092369 | ||||
Multicall | 18880561 | 365 days ago | IN | 0 ETH | 0.0091427 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
18925031 | 359 days ago | 0.00302419 ETH | ||||
18925031 | 359 days ago | 0.40196769 ETH | ||||
18925031 | 359 days ago | 0.40499188 ETH | ||||
18909549 | 361 days ago | 0.00548053 ETH | ||||
18909549 | 361 days ago | 0.00548053 ETH | ||||
18899631 | 363 days ago | 0.01840015 ETH | ||||
18899631 | 363 days ago | 0.01840015 ETH | ||||
18899321 | 363 days ago | 0.01411401 ETH | ||||
18899321 | 363 days ago | 0.989002 ETH | ||||
18899321 | 363 days ago | 1.00311601 ETH | ||||
18897936 | 363 days ago | 0.00808787 ETH | ||||
18897936 | 363 days ago | 0.00808787 ETH | ||||
18889298 | 364 days ago | 0.0048034 ETH | ||||
18889298 | 364 days ago | 0.0048034 ETH | ||||
18882986 | 365 days ago | 0.0120781 ETH | ||||
18882986 | 365 days ago | 0.0120781 ETH | ||||
18882938 | 365 days ago | 0.01293855 ETH | ||||
18882938 | 365 days ago | 0.01293855 ETH | ||||
18882915 | 365 days ago | 0.00565041 ETH | ||||
18882915 | 365 days ago | 0.00565041 ETH | ||||
18882911 | 365 days ago | 0.0079975 ETH | ||||
18882911 | 365 days ago | 0.19672566 ETH | ||||
18882911 | 365 days ago | 0.20472316 ETH | ||||
18882765 | 365 days ago | 0.00576266 ETH | ||||
18882765 | 365 days ago | 0.00576266 ETH |
Loading...
Loading
Contract Name:
ToadRouter03
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 2000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.15; import "./IToadRouter03.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./ToadswapLibrary.sol"; import "./TransferHelper.sol"; import "./IWETH.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "./IERC20Permit.sol"; import "./Multicall.sol"; import "./IPermitDai.sol"; /** * ToadRouter03 * A re-implementation of the Uniswap v2 router with bot-driven meta-transactions. * Bot private keys are all stored on a hardware wallet. * ToadRouter03 implements ERC2612 (ERC20Permit) and auto-unwrap functions */ contract ToadRouter03 is IToadRouter03, Ownable, Multicall { mapping(address => bool) allowedBots; address immutable PERMIT2; bytes32 public constant DAI_TYPEHASH = 0xea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb; modifier ensure(uint deadline) { require(deadline >= block.timestamp, "ToadRouter: EXPIRED"); _; } modifier onlyBot() { require(allowedBots[_msgSender()], "ToadRouter: UNTRUSTED"); _; } constructor( address fac, address weth, address permit ) IToadRouter03(fac, weth) { // Do any other stuff necessary // Add sender to allowedBots allowedBots[_msgSender()] = true; PERMIT2 = permit; } function addTrustedBot(address newBot) external onlyOwner { allowedBots[newBot] = true; } function removeTrustedBot(address bot) external onlyOwner { allowedBots[bot] = false; } receive() external payable { if (_msgSender() != WETH) { revert("ToadRouter: No ETH not from WETH."); } } function performPermit2Single( address owner, IAllowanceTransfer.PermitSingle memory permitSingle, bytes calldata signature ) public virtual override onlyBot { IAllowanceTransfer permitCA = IAllowanceTransfer(PERMIT2); permitCA.permit(owner, permitSingle, signature); } function performPermit2Batch( address owner, IAllowanceTransfer.PermitBatch memory permitBatch, bytes calldata signature ) public virtual override onlyBot { IAllowanceTransfer permitCA = IAllowanceTransfer(PERMIT2); permitCA.permit(owner, permitBatch, signature); } function performPermit( address owner, address tok, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override ensure(deadline) onlyBot { // There isn't actually a really easy way to check if an IERC20Permit actually meets the standard // So best we can do is try and ensure success on the selector nonces(address) - this will match Permit and Dai Permit (bool success, ) = tok.call(abi.encodeWithSelector(0x7ecebe00, owner)); require(success, "ToadRouter03: Not Permittable."); IERC20Permit ptok = IERC20Permit(tok); ptok.permit(owner, PERMIT2, type(uint256).max, deadline, v, r, s); } function performPermitDai(address owner, address tok, uint256 nonce, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override onlyBot { IPermitDai dpermit = IPermitDai(tok); // The Dai-style permit's typehash is always the same require(dpermit.PERMIT_TYPEHASH() == DAI_TYPEHASH, "ToadRouter03: Not Dai-style Permit."); dpermit.permit(owner, PERMIT2, nonce, deadline, true, v, r, s); } function stfFirstHop( uint256 amountIn, ToadStructs.DexData memory dex1, address path0, address path1, address to ) internal { TransferHelper.safeTransferFrom( PERMIT2, path0, to, ToadswapLibrary.pairFor(dex1.factory, path0, path1, dex1.initcode), amountIn ); } function swapExactTokensForTokensSupportingFeeOnTransferTokensWithWETHGas( uint amountIn, uint amountOutMin, ToadStructs.AggPath[] calldata path1, ToadStructs.AggPath[] calldata path2, address to, uint deadline, ToadStructs.FeeStruct calldata fees, ToadStructs.DexData[] calldata dexes ) public virtual override ensure(deadline) onlyBot returns (uint256 outputAmount) { // This does two half-swaps, so we can extract the gas return // Swap the first half TransferHelper.safeTransferFrom( PERMIT2, path1[0].token, to, ToadswapLibrary.pairFor( dexes[path1[1].dexId].factory, path1[0].token, path1[1].token, dexes[path1[1].dexId].initcode ), amountIn ); uint256 wethBalanceBefore = IERC20(WETH).balanceOf(address(this)); // Swap to us _swapSupportingFeeOnTransferTokens(path1, address(this), dexes); // Extract the WETH to pay the relayer IWETH(WETH).withdraw(fees.gasReturn + fees.fee); TransferHelper.safeTransferETH(tx.origin, fees.gasReturn); if (fees.fee > 0) { TransferHelper.safeTransferETH(fees.feeReceiver, fees.fee); } // Send the remaining WETH to the next hop TransferHelper.safeTransfer( path2[0].token, ToadswapLibrary.pairFor( dexes[path2[1].dexId].factory, path2[0].token, path2[1].token, dexes[path1[1].dexId].initcode ), IERC20(WETH).balanceOf(address(this)) - wethBalanceBefore ); // Grab the pre-balance uint256 balanceBefore = IERC20(path2[path2.length - 1].token).balanceOf( to ); // Run the final half of swap to the end user _swapSupportingFeeOnTransferTokens(path2, to, dexes); // Do the output amount check outputAmount = IERC20(path2[path2.length - 1].token).balanceOf(to) - (balanceBefore); require( outputAmount >= amountOutMin, "ToadRouter: INSUFFICIENT_OUTPUT_AMOUNT" ); } function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, ToadStructs.AggPath[] calldata path, address to, uint deadline, ToadStructs.FeeStruct calldata fees, uint256 ethFee, ToadStructs.AggPath[] calldata gasPath, ToadStructs.DexData[] calldata dexes ) public virtual override ensure(deadline) onlyBot returns (uint256 outputAmount) { if (fees.gasReturn + fees.fee > 0) { // Swap the gasReturn tokens from their wallet to us as WETH, unwrap and send to tx origin uint balanceBef = IERC20(WETH).balanceOf(address(this)); stfFirstHop( fees.gasReturn + fees.fee, dexes[gasPath[1].dexId], gasPath[0].token, gasPath[1].token, to ); _swapSupportingFeeOnTransferTokens(gasPath, address(this), dexes); uint256 botAmount = IERC20(WETH).balanceOf(address(this)) - balanceBef; IWETH(WETH).withdraw(botAmount); TransferHelper.safeTransferETH(tx.origin, botAmount - ethFee); if (ethFee > 0) { TransferHelper.safeTransferETH(fees.feeReceiver, ethFee); } } // Swap remaining tokens to the path provided stfFirstHop( amountIn - fees.gasReturn - fees.fee, dexes[path[1].dexId], path[0].token, path[1].token, to ); uint balanceBefore = IERC20(path[path.length - 1].token).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, to, dexes); outputAmount = IERC20(path[path.length - 1].token).balanceOf(to) - (balanceBefore); require( outputAmount >= amountOutMin, "ToadRouter: INSUFFICIENT_OUTPUT_AMOUNT" ); } function swapExactWETHforTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, ToadStructs.AggPath[] calldata path, address to, uint deadline, ToadStructs.FeeStruct calldata fees, ToadStructs.DexData[] calldata dexes ) public virtual override ensure(deadline) onlyBot returns (uint256 outputAmount) { require(path[0].token == WETH, "ToadRouter: INVALID_PATH"); // Send us gas first if (fees.gasReturn + fees.fee > 0) { TransferHelper.safeTransferFrom( PERMIT2, WETH, to, address(this), fees.gasReturn + fees.fee ); // Pay the relayer IWETH(WETH).withdraw(fees.gasReturn + fees.fee); TransferHelper.safeTransferETH(tx.origin, fees.gasReturn); if (fees.fee > 0) { TransferHelper.safeTransferETH(fees.feeReceiver, fees.fee); } } // Send to first pool stfFirstHop( amountIn - fees.gasReturn - fees.fee, dexes[path[1].dexId], path[0].token, path[1].token, to ); uint256 balanceBefore = IERC20(path[path.length - 1].token).balanceOf( to ); _swapSupportingFeeOnTransferTokens(path, to, dexes); outputAmount = IERC20(path[path.length - 1].token).balanceOf(to) - (balanceBefore); require( outputAmount >= amountOutMin, "ToadRouter: INSUFFICIENT_OUTPUT_AMOUNT" ); } function swapExactTokensForWETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, ToadStructs.AggPath[] calldata path, address to, uint deadline, ToadStructs.FeeStruct calldata fees, ToadStructs.DexData[] calldata dexes, bool unwrap ) public virtual override ensure(deadline) onlyBot returns (uint256 outputAmount) { require( path[path.length - 1].token == WETH, "ToadRouter: INVALID_PATH" ); stfFirstHop( amountIn, dexes[path[1].dexId], path[0].token, path[1].token, to ); _swapSupportingFeeOnTransferTokens(path, address(this), dexes); uint amountOut = IERC20(WETH).balanceOf(address(this)); // Adjust output amount to be exclusive of the payout of gas outputAmount = amountOut - fees.gasReturn - fees.fee; require( outputAmount >= amountOutMin, "ToadRouter: INSUFFICIENT_OUTPUT_AMOUNT" ); // Give the WETH to the holder if (unwrap) { IWETH(WETH).withdraw(outputAmount + fees.gasReturn + fees.fee); TransferHelper.safeTransferETH(to, outputAmount); } else { TransferHelper.safeTransfer(WETH, to, outputAmount); } // Pay the relayer if (fees.gasReturn + fees.fee > 0) { if (!unwrap) { IWETH(WETH).withdraw(fees.gasReturn + fees.fee); } TransferHelper.safeTransferETH(tx.origin, fees.gasReturn); if (fees.fee > 0) { TransferHelper.safeTransferETH(fees.feeReceiver, fees.fee); } } } // Gasloan WETH unwrapper function unwrapWETH( address to, uint256 amount, ToadStructs.FeeStruct calldata fees ) external virtual override onlyBot { TransferHelper.safeTransferFrom(PERMIT2, WETH, to, address(this), amount); IWETH(WETH).withdraw(amount); TransferHelper.safeTransferETH(tx.origin, fees.gasReturn); if (fees.fee > 0) { TransferHelper.safeTransferETH(fees.feeReceiver, fees.fee); } TransferHelper.safeTransferETH(to, amount - fees.gasReturn - fees.fee); } function getPriceOut( uint256 amountIn, ToadStructs.AggPath[] calldata path, ToadStructs.DexData[] calldata dexes ) public view virtual override returns (uint256[] memory amounts) { return ToadswapLibrary.getPriceOut(amountIn, path, dexes); } function _swapSupportingFeeOnTransferTokens( ToadStructs.AggPath[] memory path, address _to, ToadStructs.DexData[] memory dexes ) internal virtual { for (uint i; i < path.length - 1; i++) { (address input, address output) = ( path[i].token, path[i + 1].token ); (address token0, ) = ToadswapLibrary.sortTokens(input, output); IUniswapV2Pair pair = IUniswapV2Pair( ToadswapLibrary.pairFor( dexes[path[i + 1].dexId].factory, input, output, dexes[path[i + 1].dexId].initcode ) ); uint amountInput; uint amountOutput; { // scope to avoid stack too deep errors (uint reserve0, uint reserve1, ) = pair.getReserves(); (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput; amountOutput = ToadswapLibrary.getAmountOut( amountInput, reserveInput, reserveOutput ); } (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); address to = i < path.length - 2 ? ToadswapLibrary.pairFor( dexes[path[i + 2].dexId].factory, output, path[i + 2].token, dexes[path[i + 2].dexId].initcode ) : _to; pair.swap(amount0Out, amount1Out, to, new bytes(0)); } } // **** LIBRARY FUNCTIONS **** function quote( uint amountA, uint reserveA, uint reserveB ) public pure virtual override returns (uint amountB) { return ToadswapLibrary.quote(amountA, reserveA, reserveB); } function getAmountOut( uint amountIn, uint reserveIn, uint reserveOut ) public pure virtual override returns (uint amountOut) { return ToadswapLibrary.getAmountOut(amountIn, reserveIn, reserveOut); } function getAmountIn( uint amountOut, uint reserveIn, uint reserveOut ) public pure virtual override returns (uint amountIn) { return ToadswapLibrary.getAmountIn(amountOut, reserveIn, reserveOut); } function getAmountsOut( uint amountIn, address[] memory path ) public view virtual override returns (uint[] memory amounts) { // Adjusted to use new code - this is a uniswap-only call ToadStructs.AggPath[] memory aggPath = new ToadStructs.AggPath[]( path.length ); ToadStructs.DexData[] memory dexes = new ToadStructs.DexData[](1); dexes[0] = ToadStructs.DexData( hex"96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f", factory ); for (uint256 i = 0; i < path.length; i++) { aggPath[i] = ToadStructs.AggPath(path[i], 0); } return ToadswapLibrary.getAmountsOut(amountIn, aggPath, dexes); } function getAmountsIn( uint amountOut, address[] memory path ) public view virtual override returns (uint[] memory amounts) { // Adjusted to use new code - this is a uniswap-only call ToadStructs.AggPath[] memory aggPath = new ToadStructs.AggPath[]( path.length ); ToadStructs.DexData[] memory dexes = new ToadStructs.DexData[](1); dexes[0] = ToadStructs.DexData( hex"96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f", factory ); for (uint256 i = 0; i < path.length; i++) { aggPath[i] = ToadStructs.AggPath(path[i], 0); } return ToadswapLibrary.getAmountsIn(amountOut, aggPath, dexes); } function getAmountsOut( uint amountIn, ToadStructs.AggPath[] calldata path, ToadStructs.DexData[] calldata dexes ) external view virtual override returns (uint[] memory amounts) { return ToadswapLibrary.getAmountsOut(amountIn, path, dexes); } function getAmountsIn( uint amountOut, ToadStructs.AggPath[] calldata path, ToadStructs.DexData[] calldata dexes ) external view virtual override returns (uint[] memory amounts) { return ToadswapLibrary.getAmountsIn(amountOut, path, dexes); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions 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.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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; } }
pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint 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 (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint 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 (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); 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 (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.15; /// @title Multicall interface /// @notice Enables calling multiple methods in a single call to the contract interface IMulticall { /// @notice Call multiple functions in the current contract and return the data from all of them if they all succeed /// @dev The `msg.value` should not be trusted for any method callable from multicall. /// @param data The encoded function data for each of the calls to make to this contract /// @return results The results from each of the calls passed in via data function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; /// @title AllowanceTransfer /// @notice Handles ERC20 token permissions through signature based allowance setting and ERC20 token transfers by checking allowed amounts /// @dev Requires user's token approval on the Permit2 contract interface IAllowanceTransfer { /// @notice Thrown when an allowance on a token has expired. /// @param deadline The timestamp at which the allowed amount is no longer valid error AllowanceExpired(uint256 deadline); /// @notice Thrown when an allowance on a token has been depleted. /// @param amount The maximum amount allowed error InsufficientAllowance(uint256 amount); /// @notice Thrown when too many nonces are invalidated. error ExcessiveInvalidation(); /// @notice Emits an event when the owner successfully invalidates an ordered nonce. event NonceInvalidation( address indexed owner, address indexed token, address indexed spender, uint48 newNonce, uint48 oldNonce ); /// @notice Emits an event when the owner successfully sets permissions on a token for the spender. event Approval( address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration ); /// @notice Emits an event when the owner successfully sets permissions using a permit signature on a token for the spender. event Permit( address indexed owner, address indexed token, address indexed spender, uint160 amount, uint48 expiration, uint48 nonce ); /// @notice Emits an event when the owner sets the allowance back to 0 with the lockdown function. event Lockdown(address indexed owner, address token, address spender); /// @notice The permit data for a token struct PermitDetails { // ERC20 token address address token; // the maximum amount allowed to spend uint160 amount; // timestamp at which a spender's token allowances become invalid uint48 expiration; // an incrementing value indexed per owner,token,and spender for each signature uint48 nonce; } /// @notice The permit message signed for a single token allownce struct PermitSingle { // the permit data for a single token alownce PermitDetails details; // address permissioned on the allowed tokens address spender; // deadline on the permit signature uint256 sigDeadline; } /// @notice The permit message signed for multiple token allowances struct PermitBatch { // the permit data for multiple token allowances PermitDetails[] details; // address permissioned on the allowed tokens address spender; // deadline on the permit signature uint256 sigDeadline; } /// @notice The saved permissions /// @dev This info is saved per owner, per token, per spender and all signed over in the permit message /// @dev Setting amount to type(uint160).max sets an unlimited approval struct PackedAllowance { // amount allowed uint160 amount; // permission expiry uint48 expiration; // an incrementing value indexed per owner,token,and spender for each signature uint48 nonce; } /// @notice A token spender pair. struct TokenSpenderPair { // the token the spender is approved address token; // the spender address address spender; } /// @notice Details for a token transfer. struct AllowanceTransferDetails { // the owner of the token address from; // the recipient of the token address to; // the amount of the token uint160 amount; // the token to be transferred address token; } /// @notice A mapping from owner address to token address to spender address to PackedAllowance struct, which contains details and conditions of the approval. /// @notice The mapping is indexed in the above order see: allowance[ownerAddress][tokenAddress][spenderAddress] /// @dev The packed slot holds the allowed amount, expiration at which the allowed amount is no longer valid, and current nonce thats updated on any signature based approvals. function allowance(address, address, address) external view returns (uint160, uint48, uint48); /// @notice Approves the spender to use up to amount of the specified token up until the expiration /// @param token The token to approve /// @param spender The spender address to approve /// @param amount The approved amount of the token /// @param expiration The timestamp at which the approval is no longer valid /// @dev The packed allowance also holds a nonce, which will stay unchanged in approve /// @dev Setting amount to type(uint160).max sets an unlimited approval function approve(address token, address spender, uint160 amount, uint48 expiration) external; /// @notice Permit a spender to a given amount of the owners token via the owner's EIP-712 signature /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce /// @param owner The owner of the tokens being approved /// @param permitSingle Data signed over by the owner specifying the terms of approval /// @param signature The owner's signature over the permit data function permit(address owner, PermitSingle memory permitSingle, bytes calldata signature) external; /// @notice Permit a spender to the signed amounts of the owners tokens via the owner's EIP-712 signature /// @dev May fail if the owner's nonce was invalidated in-flight by invalidateNonce /// @param owner The owner of the tokens being approved /// @param permitBatch Data signed over by the owner specifying the terms of approval /// @param signature The owner's signature over the permit data function permit(address owner, PermitBatch memory permitBatch, bytes calldata signature) external; /// @notice Transfer approved tokens from one address to another /// @param from The address to transfer from /// @param to The address of the recipient /// @param amount The amount of the token to transfer /// @param token The token address to transfer /// @dev Requires the from address to have approved at least the desired amount /// of tokens to msg.sender. function transferFrom(address from, address to, uint160 amount, address token) external; /// @notice Transfer approved tokens in a batch /// @param transferDetails Array of owners, recipients, amounts, and tokens for the transfers /// @dev Requires the from addresses to have approved at least the desired amount /// of tokens to msg.sender. function transferFrom(AllowanceTransferDetails[] calldata transferDetails) external; /// @notice Enables performing a "lockdown" of the sender's Permit2 identity /// by batch revoking approvals /// @param approvals Array of approvals to revoke. function lockdown(TokenSpenderPair[] calldata approvals) external; /// @notice Invalidate nonces for a given (token, spender) pair /// @param token The token to invalidate nonces for /// @param spender The spender to invalidate nonces for /// @param newNonce The new nonce to set. Invalidates all nonces less than it. /// @dev Can't invalidate more than 2**16 nonces per transaction. function invalidateNonces(address token, address spender, uint48 newNonce) external; }
// SPDX-License-Identifier: AGPL-3.0-or-later // Just an interface for Dai's permits pragma solidity ^0.8.17; abstract contract IPermitDai { function permit(address holder, address spender, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external virtual; // Defining details for checking function PERMIT_TYPEHASH() public virtual returns (bytes32); function nonces(address) public virtual returns (uint256); }
/// SPDX-License-Identifier: NONE pragma solidity ^0.8.15; import "./ToadStructs.sol"; import "./IMulticall.sol"; import "./IPermit2/IAllowanceTransfer.sol"; /** * IToadRouter03 * Extends the V1 router with auto-unwrap functions and permit2 support - also implements Multicall * Also has a proper price calculator */ abstract contract IToadRouter03 is IMulticall { /** * Run a permit on a token to the Permit2 contract for max uint256 * @param owner the token owner * @param tok the token to permit * @param deadline A deadline to expire by * @param v v of the sig * @param r r of the sig * @param s s of the sig */ function performPermit(address owner, address tok, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual; /** * Run a permit on a token to the Permit2 contract via the Dai-style permit * @param owner the token owner * @param tok the token to permit * @param deadline A deadline to expire by * @param nonce the nonce * @param v v of the sig * @param r r of the sig * @param s s of the sig */ function performPermitDai(address owner, address tok, uint256 nonce, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual; /** * Run a Permit2 permit on a token to be spent by us * @param owner The tokens owner * @param permitSingle The struct * @param signature The signature */ function performPermit2Single(address owner, IAllowanceTransfer.PermitSingle memory permitSingle, bytes calldata signature) public virtual; /** * Run a batch of Permit2 permits on a token to be spent by us * @param owner The tokens owner * @param permitBatch The struct * @param signature The signature */ function performPermit2Batch(address owner, IAllowanceTransfer.PermitBatch memory permitBatch, bytes calldata signature) public virtual; function swapExactTokensForTokensSupportingFeeOnTransferTokensWithWETHGas(uint amountIn, uint amountOutMin, ToadStructs.AggPath[] calldata path1, ToadStructs.AggPath[] calldata path2, address to, uint deadline, ToadStructs.FeeStruct calldata fees, ToadStructs.DexData[] calldata dexes) public virtual returns(uint256 outputAmount); function swapExactTokensForWETHSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, ToadStructs.AggPath[] calldata path, address to, uint deadline, ToadStructs.FeeStruct calldata fees, ToadStructs.DexData[] calldata dexes, bool unwrap) public virtual returns(uint256 outputAmount); function swapExactWETHforTokensSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, ToadStructs.AggPath[] calldata path, address to, uint deadline, ToadStructs.FeeStruct calldata fees, ToadStructs.DexData[] calldata dexes) public virtual returns(uint256 outputAmount); function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, ToadStructs.AggPath[] calldata path, address to, uint deadline, ToadStructs.FeeStruct calldata fees, uint256 ethFee, ToadStructs.AggPath[] calldata gasPath, ToadStructs.DexData[] calldata dexes) public virtual returns(uint256 outputAmount); function getPriceOut(uint256 amountIn, ToadStructs.AggPath[] calldata path, ToadStructs.DexData[] calldata dexes) public view virtual returns (uint256[] memory amounts); function getAmountsOut(uint amountIn, ToadStructs.AggPath[] calldata path, ToadStructs.DexData[] calldata dexes) external view virtual returns (uint[] memory amounts); function getAmountsIn(uint amountOut, ToadStructs.AggPath[] calldata path, ToadStructs.DexData[] calldata dexes) external view virtual returns (uint[] memory amounts); // IToadRouter01 string public versionRecipient = "3.0.0"; address public immutable factory; address public immutable WETH; constructor(address fac, address weth) { factory = fac; WETH = weth; } function unwrapWETH(address to, uint256 amount, ToadStructs.FeeStruct calldata fees) external virtual; function quote(uint amountA, uint reserveA, uint reserveB) external pure virtual returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure virtual returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure virtual returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view virtual returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view virtual returns (uint[] memory amounts); } //swapExactTokensForTokensSupportingFeeOnTransferTokensWithWETHGas(uint256,uint256,(address,uint96)[],(address,uint96)[],address,uint256,(uint256,address,uint96),(bytes32,address)[])
pragma solidity ^0.8.15; interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.15; import './IMulticall.sol'; /// @title Multicall /// @notice Enables calling multiple methods in a single call to the contract abstract contract Multicall is IMulticall { /// @inheritdoc IMulticall function multicall(bytes[] calldata data) public payable override returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(data[i]); if (!success) { // Next 5 lines from https://ethereum.stackexchange.com/a/83577 if (result.length < 68) revert(); assembly { result := add(result, 0x04) } revert(abi.decode(result, (string))); } results[i] = result; } } }
// SPDX-License-Identifier: NONE pragma solidity ^0.8.15; contract ToadStructs { /** * token: The token * dexId: the position of the dex struct in the list provided - should be the same between input and output token */ struct AggPath { address token; uint96 dexId; } /** * DexData - a list of UniV2 dexes referred to in AggPath - shared between gasPath and path * initcode: the initcode to feed the create2 seed * factory: the factory address to feed the create2 seed */ struct DexData { bytes32 initcode; address factory; } /** * FeeStruct - a batch of fees to be paid in gas and optionally to another account */ struct FeeStruct { uint256 gasReturn; address feeReceiver; uint96 fee; } }
/** * Modified version of the UniswapV2Library to use inbuilt SafeMath * Also now supports */ //SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.15; import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; import './ToadStructs.sol'; library ToadswapLibrary { // returns sorted token addresses, used to handle return values from pairs sorted in this order function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { require(tokenA != tokenB, 'ToadswapLibrary: IDENTICAL_ADDRESSES'); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), 'ToadswapLibrary: ZERO_ADDRESS'); } // calculates the CREATE2 address for a UniswapV2 pair without making any external calls function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) { pair = pairFor(factory, tokenA, tokenB, hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f'); } function pairFor(address factory, address tokenA, address tokenB, bytes32 initCodeHash) internal pure returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); pair = address(uint160(uint256(keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), initCodeHash // init code hash ))))); } function getPriceOut(uint256 amountIn, ToadStructs.AggPath[] calldata path, ToadStructs.DexData[] calldata dexes) internal view returns (uint256[] memory amounts) { require(path.length >= 2, 'ToadswapLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { (uint reserveIn, uint reserveOut) = getReserves(dexes[path[i+1].dexId].factory, path[i].token, path[i + 1].token, dexes[path[i+1].dexId].initcode); amounts[i + 1] = quote(amounts[i], reserveIn, reserveOut); } } // fetches and sorts the reserves for a pair function getReserves(address factory, address tokenA, address tokenB, bytes32 initCodeHash) internal view returns (uint reserveA, uint reserveB) { (address token0,) = sortTokens(tokenA, tokenB); (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB, initCodeHash)).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { require(amountA > 0, 'ToadswapLibrary: INSUFFICIENT_AMOUNT'); require(reserveA > 0 && reserveB > 0, 'ToadswapLibrary: INSUFFICIENT_LIQUIDITY'); amountB = amountA * (reserveB) / reserveA; } // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { require(amountIn > 0, 'ToadswapLibrary: INSUFFICIENT_INPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0, 'ToadswapLibrary: INSUFFICIENT_LIQUIDITY'); uint amountInWithFee = amountIn * 997; uint numerator = amountInWithFee * reserveOut; uint denominator = (reserveIn * 1000) + amountInWithFee; amountOut = numerator / denominator; } // given an output amount of an asset and pair reserves, returns a required input amount of the other asset function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { require(amountOut > 0, 'ToadswapLibrary: INSUFFICIENT_OUTPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0, 'ToadswapLibrary: INSUFFICIENT_LIQUIDITY'); uint numerator = reserveIn * amountOut * 1000; uint denominator = (reserveOut - amountOut) * 997; amountIn = (numerator / denominator) + 1; } // performs chained getAmountOut calculations on any number of pairs function getAmountsOut(uint amountIn, ToadStructs.AggPath[] memory path, ToadStructs.DexData[] memory dexes) internal view returns (uint[] memory amounts) { require(path.length >= 2, 'ToadswapLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { (uint reserveIn, uint reserveOut) = getReserves(dexes[path[i+1].dexId].factory, path[i].token, path[i + 1].token, dexes[path[i+1].dexId].initcode); amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); } } // performs chained getAmountIn calculations on any number of pairs function getAmountsIn(uint amountOut, ToadStructs.AggPath[] memory path, ToadStructs.DexData[] memory dexes) internal view returns (uint[] memory amounts) { require(path.length >= 2, 'ToadswapLibrary: INVALID_PATH'); amounts = new uint[](path.length); amounts[amounts.length - 1] = amountOut; for (uint i = path.length - 1; i > 0; i--) { (uint reserveIn, uint reserveOut) = getReserves(dexes[path[i].dexId].factory, path[i - 1].token, path[i].token, dexes[path[i].dexId].initcode); amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut); } } }
//SPDX-License-Identifier: GPL-3.0 // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false // Modified by TBC to use Permit2's transferFrom import "./IPermit2/IAllowanceTransfer.sol"; pragma solidity ^0.8.15; library TransferHelper { function safeApprove(address token, address to, uint value) internal { // bytes4(keccak256(bytes('approve(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED'); } function safeTransfer(address token, address to, uint value) internal { // bytes4(keccak256(bytes('transfer(address,uint256)'))); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED'); } function safeTransferFrom(address permit2, address token, address from, address to, uint value) internal { // bytes4(keccak256(bytes('transferFrom(address,address,uint160,address)'))); IAllowanceTransfer permitter = IAllowanceTransfer(permit2); permitter.transferFrom(from, to, uint160(value), token); } function safeTransferETH(address to, uint value) internal { (bool success,) = to.call{value:value}(new bytes(0)); require(success, 'TransferHelper: ETH_TRANSFER_FAILED'); } }
{ "optimizer": { "enabled": true, "runs": 2000 }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"fac","type":"address"},{"internalType":"address","name":"weth","type":"address"},{"internalType":"address","name":"permit","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"DAI_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newBot","type":"address"}],"name":"addTrustedBot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"path","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"initcode","type":"bytes32"},{"internalType":"address","name":"factory","type":"address"}],"internalType":"struct ToadStructs.DexData[]","name":"dexes","type":"tuple[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"path","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"initcode","type":"bytes32"},{"internalType":"address","name":"factory","type":"address"}],"internalType":"struct ToadStructs.DexData[]","name":"dexes","type":"tuple[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"path","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"initcode","type":"bytes32"},{"internalType":"address","name":"factory","type":"address"}],"internalType":"struct ToadStructs.DexData[]","name":"dexes","type":"tuple[]"}],"name":"getPriceOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"tok","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"performPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"uint48","name":"expiration","type":"uint48"},{"internalType":"uint48","name":"nonce","type":"uint48"}],"internalType":"struct IAllowanceTransfer.PermitDetails[]","name":"details","type":"tuple[]"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"sigDeadline","type":"uint256"}],"internalType":"struct IAllowanceTransfer.PermitBatch","name":"permitBatch","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"performPermit2Batch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"components":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint160","name":"amount","type":"uint160"},{"internalType":"uint48","name":"expiration","type":"uint48"},{"internalType":"uint48","name":"nonce","type":"uint48"}],"internalType":"struct IAllowanceTransfer.PermitDetails","name":"details","type":"tuple"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"sigDeadline","type":"uint256"}],"internalType":"struct IAllowanceTransfer.PermitSingle","name":"permitSingle","type":"tuple"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"performPermit2Single","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"tok","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"performPermitDai","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"bot","type":"address"}],"name":"removeTrustedBot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"path","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"components":[{"internalType":"uint256","name":"gasReturn","type":"uint256"},{"internalType":"address","name":"feeReceiver","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"internalType":"struct ToadStructs.FeeStruct","name":"fees","type":"tuple"},{"internalType":"uint256","name":"ethFee","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"gasPath","type":"tuple[]"},{"components":[{"internalType":"bytes32","name":"initcode","type":"bytes32"},{"internalType":"address","name":"factory","type":"address"}],"internalType":"struct ToadStructs.DexData[]","name":"dexes","type":"tuple[]"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"path1","type":"tuple[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"path2","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"components":[{"internalType":"uint256","name":"gasReturn","type":"uint256"},{"internalType":"address","name":"feeReceiver","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"internalType":"struct ToadStructs.FeeStruct","name":"fees","type":"tuple"},{"components":[{"internalType":"bytes32","name":"initcode","type":"bytes32"},{"internalType":"address","name":"factory","type":"address"}],"internalType":"struct ToadStructs.DexData[]","name":"dexes","type":"tuple[]"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokensWithWETHGas","outputs":[{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"path","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"components":[{"internalType":"uint256","name":"gasReturn","type":"uint256"},{"internalType":"address","name":"feeReceiver","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"internalType":"struct ToadStructs.FeeStruct","name":"fees","type":"tuple"},{"components":[{"internalType":"bytes32","name":"initcode","type":"bytes32"},{"internalType":"address","name":"factory","type":"address"}],"internalType":"struct ToadStructs.DexData[]","name":"dexes","type":"tuple[]"},{"internalType":"bool","name":"unwrap","type":"bool"}],"name":"swapExactTokensForWETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"dexId","type":"uint96"}],"internalType":"struct ToadStructs.AggPath[]","name":"path","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"components":[{"internalType":"uint256","name":"gasReturn","type":"uint256"},{"internalType":"address","name":"feeReceiver","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"internalType":"struct ToadStructs.FeeStruct","name":"fees","type":"tuple"},{"components":[{"internalType":"bytes32","name":"initcode","type":"bytes32"},{"internalType":"address","name":"factory","type":"address"}],"internalType":"struct ToadStructs.DexData[]","name":"dexes","type":"tuple[]"}],"name":"swapExactWETHforTokensSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"outputAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"components":[{"internalType":"uint256","name":"gasReturn","type":"uint256"},{"internalType":"address","name":"feeReceiver","type":"address"},{"internalType":"uint96","name":"fee","type":"uint96"}],"internalType":"struct ToadStructs.FeeStruct","name":"fees","type":"tuple"}],"name":"unwrapWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"versionRecipient","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e034620001e857601f620042de38819003918201601f19168301916001600160401b03831184841017620001ed57808492606094604052833981010312620001e8576200004d8162000203565b620000696040620000616020850162000203565b930162000203565b906000928354916001928381811c91168015620001dd575b6020821014620001c957601f81116200019a575b50600a640332e302e360dc1b01855560805260a0528054336001600160a01b0319821681178355604080519590929091906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a33381526002602052209060ff1982541617905560c0526140c590816200021982396080518181816106f101528181611a860152611b0a015260a051818181610f38015281816117e20152818161187101528181611f18015281816124da01528181612cc90152612f92015260c0518181816108d3015281816111c2015281816113de015281816118990152818161201f01528181612173015281816124990152612ed30152f35b85805283601f60208820920160051c8201915b828110620001bd57505062000095565b878155018490620001ad565b634e487b7160e01b86526022600452602486fd5b90607f169062000081565b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b0382168203620001e85756fe60806040526004361015610023575b361561001957600080fd5b610021611f0e565b005b60003560e01c8063054d50d41461023f57806318232776146102365780631f00ca741461022d57806322aeedc314610224578063307ab24b1461021b57806331e7d53a146102125780634000120214610209578063412f845b14610200578063486ff0cd146101f757806350087bdf146101ee5780636652dd6d146101e5578063715018a6146101dc57806385f8c259146101d3578063880fbf0a146101ca5780638da5cb5b146101c15780638db7ac9a146101b85780638feca794146101af578063ac9650d8146101a6578063ad5c46481461019d578063ad615dec14610194578063b23c19e61461018b578063b43ba43114610182578063c09d54e514610179578063c45a015514610170578063d06ca61f14610167578063d83af6871461015e5763f2fde38b0361000e57610159611bc0565b61000e565b50610159611b74565b50610159611aaa565b50610159611a65565b506101596119cf565b50610159611986565b50610159611820565b50610159611806565b506101596117c1565b506101596116bf565b5061015961161e565b50610159611597565b5061015961156f565b506101596114d6565b506101596114bc565b50610159611447565b506101596112cf565b50610159610e8d565b50610159610d86565b50610159610cf3565b50610159610cb7565b50610159610b64565b50610159610a78565b506101596107d2565b50610159610691565b506101596104c1565b50610159610267565b600319606091011261026257600435906024359060443590565b600080fd5b503461026257602061028161027b36610248565b91613b2a565b604051908152f35b6001600160a01b0381160361026257565b606435906102a782610289565b565b608435906102a782610289565b35906102a782610289565b50634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff8211176102f457604052565b6102fc6102c1565b604052565b6060810190811067ffffffffffffffff8211176102f457604052565b6040810190811067ffffffffffffffff8211176102f457604052565b67ffffffffffffffff81116102f457604052565b6020810190811067ffffffffffffffff8211176102f457604052565b90601f601f19910116810190811067ffffffffffffffff8211176102f457604052565b604051906102a78261031d565b60209067ffffffffffffffff81116103b3575b60051b0190565b6103bb6102c1565b6103ac565b359065ffffffffffff8216820361026257565b602319608091011261026257604051906103ec826102d8565b816024356103f981610289565b815260443561040781610289565b602082015265ffffffffffff90606435828116810361026257604082015260843591821682036102625760600152565b91908260809103126102625760405161044f816102d8565b606061048e818395803561046281610289565b8552602081013561047281610289565b6020860152610483604082016103c0565b6040860152016103c0565b910152565b9181601f840112156102625782359167ffffffffffffffff8311610262576020838186019501011161026257565b503461026257600319606081360112610262576004356104e081610289565b6024359067ffffffffffffffff92838311610262576060908336030112610262576040519161050e83610301565b8060040135848111610262578101366023820112156102625760048101359061053682610399565b906105446040519283610369565b82825260209260248484019160071b8301019136831161026257602401905b8282106105ad5750505084526044919061057f602483016102b6565b9085015201356040830152604435928311610262576105a5610021933690600401610493565b929091612148565b846080916105bb3685610437565b815201910190610563565b906040600319830112610262576004359160243567ffffffffffffffff811161026257816023820112156102625780600401359161060383610399565b926106116040519485610369565b80845260209260248486019260051b82010192831161026257602401905b82821061063d575050505090565b838091833561064b81610289565b81520191019061062f565b6020908160408183019282815285518094520193019160005b82811061067d575050505090565b83518552938101939281019260010161066f565b5034610262576106a0366105c6565b906106ab8251613680565b916106b46136cf565b604051916106c18361031d565b7f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f83526020926001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168482015261071e83611ed6565b5261072882611ed6565b50600091825b8251811015610794578061075561074861078f9386611eec565b516001600160a01b031690565b61076f61076061038c565b6001600160a01b039092168252565b858782015261077e828a611eec565b526107898189611eec565b50611d6d565b61072e565b6107ae6107a2838989613dc0565b60405191829182610656565b0390f35b6084359060ff8216820361026257565b6064359060ff8216820361026257565b50346102625760e0600319360112610262576001600160a01b036004356107f881610289565b60243561080481610289565b61080c6107b2565b6000938492338452600260205261082960ff604086205416611faa565b166108947fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6040517f30adf81f00000000000000000000000000000000000000000000000000000000815260208160048189885af19081156109a3575b8691610975575b501461233d565b803b15610971576040517f8fcbaf0c0000000000000000000000000000000000000000000000000000000081526001600160a01b0394851660048201527f0000000000000000000000000000000000000000000000000000000000000000949094166024850152604480359085015260648035908501526001608485015260ff90911660a4808501919091523560c4808501919091523560e4840152829081838161010481015b03925af18015610964575b61094e575080f35b8061095b61096192610339565b80610cac565b80f35b61096c61213b565b610946565b8280fd5b610996915060203d811161099c575b61098e8183610369565b81019061232e565b3861088d565b503d610984565b6109ab61213b565b610886565b9181601f840112156102625782359167ffffffffffffffff8311610262576020808501948460061b01011161026257565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c60609101126102625760a490565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc606091011261026257604490565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c60609101126102625760c490565b8015150361026257565b5034610262576101406003193601126102625767ffffffffffffffff60443581811161026257610aac9036906004016109b0565b6064359291610aba84610289565b610ac3366109e1565b9361010435938411610262576107ae94610ae4610b049536906004016109b0565b9390926101243595610af587610a6e565b60843592602435600435612f42565b6040519081529081906020820190565b906060600319830112610262576004359167ffffffffffffffff916024358381116102625782610b46916004016109b0565b9390939260443591821161026257610b60916004016109b0565b9091565b503461026257610b7336610b14565b91610b8560028296959396101561389c565b610b8e816138e7565b93610b9885611ed6565b5260005b610ba5826129fe565b811015610c9e5760208080610bb9846129cd565b610bc4908688612855565b01610bce90612893565b6bffffffffffffffffffffffff16610be790878a612855565b01610bf190612873565b90610bfd838587612855565b610c0690612873565b90610c10846129cd565b610c1b908688612855565b610c2490612873565b90610c2e856129cd565b610c39908789612855565b01610c4390612893565b6bffffffffffffffffffffffff16610c5c90888b612855565b3591610c6793613918565b610c718388611eec565b5191610c7c92613a8e565b610c85826129cd565b610c8f9087611eec565b52610c9990611d6d565b610b9c565b604051806107ae8782610656565b600091031261026257565b50346102625760006003193601126102625760206040517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb8152f35b5034610262576107ae6107a2610d1c610d24610d0e36610b14565b94939591929092369161289d565b923691612971565b91613dc0565b60005b838110610d3d5750506000910152565b8181015183820152602001610d2d565b90601f19601f602093610d6b81518092818752878088019101610d2a565b0116010190565b906020610d83928181520190610d4d565b90565b503461026257600080600319360112610e8a57604051908080549060019180831c92808216928315610e80575b6020928386108514610e6c578588526020880194908115610e4b5750600114610df3575b6107ae87610de781890382610369565b60405191829182610d72565b6000805294509192917f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b838610610e3a5750505091019050610de7826107ae3880610dd7565b805485870152948201948101610e1e565b60ff191685525050505090151560051b019050610de7826107ae3880610dd7565b602482634e487b7160e01b81526022600452fd5b93607f1693610db3565b80fd5b5034610262576101206003193601126102625760443567ffffffffffffffff80821161026257610ec2600492369084016109b0565b909260643591610ed183610289565b610eda366109e1565b936101043590811161026257610ef390369084016109b0565b610f04949194426084351015612298565b60009333855260209360028552604097610f2360ff8a89205416611faa565b84610f36610f31848d612835565b612873565b7f0000000000000000000000000000000000000000000000000000000000000000926001600160a01b0380851692610f7091168314612ef7565b8035918c820194610f9d610f97610f8688612893565b6bffffffffffffffffffffffff1690565b856129f1565b61119f575b50505061101792610fc3610f86610fbd610fc9948935612a3a565b92612893565b90612a3a565b8b610feb610fe4610f868b610fde8986612846565b01612893565b888d612855565b91611011611009610f3188611003610f318288612835565b95612846565b933690612921565b90612eaf565b611040611034611034610f318c8561102e816129fe565b91612855565b6001600160a01b031690565b9288519786896370a0823160e01b9687825281806110708b8a83019190916001600160a01b036020820193169052565b03915afa988915611192575b8899611150575b50926110cd611034611034610f316107ae9e8a976110c46111099f9e9d9b986110f09d6110be8e9d6110b636878961289d565b933691612971565b916132e7565b61102e816129fe565b918a5196879485938493845283019190916001600160a01b036020820193169052565b03915afa928315611143575b92611126575b5050612a3a565b90611118602435831015612a47565b519081529081906020820190565b61113c9250803d1061099c5761098e8183610369565b3880611102565b61114b61213b565b6110fc565b86939950958795929686959299983d871161118b575b6111708183610369565b810161117b9161232e565b9993969295509790939697611083565b503d611166565b61119a61213b565b61107c565b6111e691929394506111bc6111b6610f8688612893565b866129f1565b908a30917f0000000000000000000000000000000000000000000000000000000000000000613f72565b6111fb6111f5610f8686612893565b846129f1565b90803b156112cb57610f86610fbd8a958f610fc9968f8f92906110179b98610fc3988f836112409551809681958294632e1a7d4d60e01b845283019190602083019252565b03925af180156112be575b6112ab575b5061125b8332613ffe565b6bffffffffffffffffffffffff61127188612893565b16611284575b5050945050829550610fa2565b6112a4916112929101612873565b61129e610f8688612893565b90613ffe565b8c38611277565b8061095b6112b892610339565b38611250565b6112c661213b565b61124b565b8a80fd5b50346102625760c0600319360112610262576001600160a01b036004356112f581610289565b60243561130181610289565b60443561130c6107c2565b9261131942831015612298565b6000948593338552600260205261133660ff604087205416611faa565b6040517f7ecebe0000000000000000000000000000000000000000000000000000000000602082019081526001600160a01b038516602480840191909152825261139d9187918291611389604482610369565b519082865af1611397611e47565b506122e3565b1690813b15611443576040517fd505accf0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009190911660248201526000196044820152606481019290925260ff9093166084808301919091523560a4808301919091523560c482015291829081838160e4810161093b565b8380fd5b503461026257600080600319360112610e8a57611462611cb5565b806001600160a01b036001547fffffffffffffffffffffffff00000000000000000000000000000000000000008116600155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50346102625760206102816114d036610248565b91613c0f565b5034610262576101606003193601126102625767ffffffffffffffff6044358181116102625761150a9036906004016109b0565b919061151461029a565b61151d366109e1565b9361012435848111610262576115379036906004016109b0565b9161014435958611610262576107ae96611558610b049736906004016109b0565b969095610104359360843592602435600435612ab8565b50346102625760006003193601126102625760206001600160a01b0360015416604051908152f35b503461026257610100600319360112610262576004356115b681610289565b60c0602319360112610262576040516115ce81610301565b6115d7366103d3565b815260a4356115e581610289565b602082015260c435604082015260e4359167ffffffffffffffff831161026257611616610021933690600401610493565b929091611ff5565b5034610262576107ae6107a2610d1c611639610d0e36610b14565b91613cdd565b602080820190808352835180925260408301928160408460051b8301019501936000915b8483106116735750505050505090565b90919293949584806116af837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc086600196030187528a51610d4d565b9801930193019194939290611663565b506020600319360112610262576004803567ffffffffffffffff918282116102625736602383011215610262578181013592831161026257602490818301928236918660051b0101116102625761171584611d0d565b9360005b81811061172e57604051806107ae888261163f565b60008061173c838589611da0565b6040939161174e855180938193611e0e565b0390305af49061175c611e47565b9182901561178557505090611780916117758289611eec565b526107898188611eec565b611719565b86838792604482511061026257826117bd93856117a89401518301019101611e77565b925192839262461bcd60e51b84528301610d72565b0390fd5b50346102625760006003193601126102625760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461026257602061028161181a36610248565b91613a8e565b50346102625760a06003193601126102625760043561183e81610289565b6024359061184b36610a10565b90600092338452600260205261186760ff604086205416611faa565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000006118bd833086847f0000000000000000000000000000000000000000000000000000000000000000613f72565b1692833b1561198257610fc3610f86610fbd61129e9461096197896040518092632e1a7d4d60e01b82528183816118fc88600483019190602083019252565b03925af18015611975575b611962575b5084359061191a8232613ffe565b60408601956bffffffffffffffffffffffff61193588612893565b16611941575b50612a3a565b611950602061195c9201612873565b61129e610f8689612893565b3861193b565b8061095b61196f92610339565b3861190c565b61197d61213b565b611907565b8480fd5b5034610262576020600319360112610262576001600160a01b036004356119ac81610289565b6119b4611cb5565b166000526002602052604060002060ff198154169055600080f35b5034610262576101406003193601126102625767ffffffffffffffff60443581811161026257611a039036906004016109b0565b919060643582811161026257611a1d9036906004016109b0565b939091611a286102a9565b90611a3236610a3f565b9161012435958611610262576107ae96611a53610b049736906004016109b0565b96909560a435946024356004356123ae565b50346102625760006003193601126102625760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b503461026257611ab9366105c6565b90611ac48251613680565b91611acd6136cf565b60405191611ada8361031d565b7f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f83526020926001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001684820152611b3783611ed6565b52611b4182611ed6565b50600091825b8251811015611b665780610755610748611b619386611eec565b611b47565b6107ae6107a2838989613cdd565b5034610262576020600319360112610262576001600160a01b03600435611b9a81610289565b611ba2611cb5565b1660005260026020526040600020600160ff19825416179055600080f35b503461026257602060031936011261026257600435611bde81610289565b611be6611cb5565b6001600160a01b03809116908115611c4b57600154827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617600155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b608460405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b6001600160a01b03600154163303611cc957565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b90611d1782610399565b611d246040519182610369565b828152601f19611d348294610399565b019060005b828110611d4557505050565b806060602080938501015201611d39565b50634e487b7160e01b600052601160045260246000fd5b6001906000198114611d7d570190565b611d85611d56565b0190565b50634e487b7160e01b600052603260045260246000fd5b9190811015611e01575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561026257019081359167ffffffffffffffff8311610262576020018236038113610262579190565b611e09611d89565b611daa565b908092918237016000815290565b601f19601f60209267ffffffffffffffff8111611e3a575b01160190565b611e426102c1565b611e34565b3d15611e72573d90611e5882611e1c565b91611e666040519384610369565b82523d6000602084013e565b606090565b6020818303126102625780519067ffffffffffffffff8211610262570181601f82011215610262578051611eaa81611e1c565b92611eb86040519485610369565b8184526020828401011161026257610d839160208085019101610d2a565b602090805115611ee4570190565b611d85611d89565b6020918151811015611f01575b60051b010190565b611f09611d89565b611ef9565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163303611f4057565b608460405162461bcd60e51b815260206004820152602160248201527f546f6164526f757465723a204e6f20455448206e6f742066726f6d205745544860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152fd5b15611fb157565b606460405162461bcd60e51b815260206004820152601560248201527f546f6164526f757465723a20554e5452555354454400000000000000000000006044820152fd5b919092600092338452600260205261201360ff604086205416611faa565b6001600160a01b0392837f00000000000000000000000000000000000000000000000000000000000000001692833b1561211657916120ea86928694604080519a8b998a9889977f2b67b5700000000000000000000000000000000000000000000000000000000089521660048801526120c56024880183516060906001600160a01b0380825116845260208201511660208401528165ffffffffffff91826040820151166040860152015116910152565b60208201511660a4870152015160c485015261010060e485015261010484019161211a565b03925af18015612109575b6120fc5750565b8061095b6102a792610339565b61211161213b565b6120f5565b8580fd5b601f8260209493601f19938186528686013760008582860101520116010190565b506040513d6000823e3d90fd5b92916000923384526020916002835261216760ff604087205416611faa565b6001600160a01b0393847f00000000000000000000000000000000000000000000000000000000000000001694853b15612294579694939186939188604051998a987f2a2d80d1000000000000000000000000000000000000000000000000000000008a521660048901526060602489015260c4880194825195606060648b015286518091528160e48b01970190885b81811061222d575050508201511660848801526040015160a487015285830360031901604487015285939284926120ea9261211a565b929496985092949681999a5060808161227e8793600195516060906001600160a01b0380825116845260208201511660208401528165ffffffffffff91826040820151166040860152015116910152565b0199019101908b99989694928b989694926121f7565b8680fd5b1561229f57565b606460405162461bcd60e51b815260206004820152601360248201527f546f6164526f757465723a2045585049524544000000000000000000000000006044820152fd5b156122ea57565b606460405162461bcd60e51b815260206004820152601e60248201527f546f6164526f7574657230333a204e6f74205065726d69747461626c652e00006044820152fd5b90816020910312610262575190565b1561234457565b608460405162461bcd60e51b815260206004820152602360248201527f546f6164526f7574657230333a204e6f74204461692d7374796c65205065726d60448201527f69742e00000000000000000000000000000000000000000000000000000000006064820152fd5b9398979296999099959491954211156123c690612298565b60009633885260209660028852604095868a205460ff166123e690611faa565b6123f08383612835565b6123f990612873565b90898c86826124088888612846565b0161241290612893565b6bffffffffffffffffffffffff169061242a92612855565b0161243490612873565b8c8b6124408787612835565b61244990612873565b91886124558989612846565b61245e90612873565b926124698a8a612846565b0161247390612893565b6bffffffffffffffffffffffff169061248b92612855565b3591612496936137e7565b897f0000000000000000000000000000000000000000000000000000000000000000936124c294613f72565b85516370a0823160e01b8082523060048301529590927f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316918a85602481865afa948515612828575b8c95612809575b5061253e8d61253661252d36868961289d565b91893691612971565b9030906132e7565b88810190612558612551610f8684612893565b82356129f1565b843b15612805578f93919289938f8f939061258b918f5180938192632e1a7d4d60e01b8352600483019190602083019252565b0381838c5af180156127f8575b6127e5575b506125a9813532613ffe565b6bffffffffffffffffffffffff6125bf83612893565b166127c9575b5050878f916125d48587612835565b6125dd90612873565b9781806125ea888a612846565b016125f490612893565b6bffffffffffffffffffffffff1661260d908587612855565b0161261790612873565b966126228782612835565b61262b90612873565b9661263591612846565b61263e90612873565b9461264891612846565b0161265290612893565b6bffffffffffffffffffffffff169061266a92612855565b3591612675936137e7565b875187815230600482015290918a90829060249082905afa938415946126aa926126b0966127bc575b8d916127a55750612a3a565b91613e89565b6126c7611034611034610f318c8661102e816129fe565b84518481526001600160a01b0387166004820152989087908a9060249082905afa988915612798575b8899612756575b509261272a611034611034610f31610d839d8a976110c461274d9f9e9d9b986110f09d6110be8e9d6110b636878961289d565b91518096819482938352600483019190916001600160a01b036020820193169052565b91821015612a47565b86939950958795929686959299983d8711612791575b6127768183610369565b81016127819161232e565b99939692955097909396976126f7565b503d61276c565b6127a061213b565b6126f0565b61195c91508c8d3d1061099c5761098e8183610369565b6127c461213b565b61269e565b610f86610fbd6127dd9461129e9301612873565b8b38806125c5565b8061095b6127f292610339565b3861259d565b61280061213b565b612598565b8d80fd5b6128219195508b3d8d1161099c5761098e8183610369565b933861251a565b61283061213b565b612513565b901561283e5790565b610d83611d89565b60409160011015611ee4570190565b9190811015612866575b60061b0190565b61286e611d89565b61285f565b35610d8381610289565b6bffffffffffffffffffffffff81160361026257565b35610d838161287d565b9291926128a982610399565b6040926128b884519283610369565b819581835260208093019160061b84019381851161026257915b8483106128e157505050505050565b85838303126102625783869182516128f88161031d565b853561290381610289565b8152828601356129128161287d565b838201528152019201916128d2565b9190826040910312610262576040516040810181811067ffffffffffffffff821117612964575b60405260208082948035845201359161296083610289565b0152565b61296c6102c1565b612948565b92919261297d82610399565b60409261298c84519283610369565b819581835260208093019160061b84019381851161026257915b8483106129b557505050505050565b8386916129c28486612921565b8152019201916129a6565b90600182018092116129db57565b6102a7611d56565b90600282018092116129db57565b919082018092116129db57565b9060001982019182116129db57565b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe82019182116129db57565b919082039182116129db57565b15612a4e57565b608460405162461bcd60e51b815260206004820152602660248201527f546f6164526f757465723a20494e53554646494349454e545f4f55545055545f60448201527f414d4f554e5400000000000000000000000000000000000000000000000000006064820152fd5b93999894612ad2909b98919b979297969396421115612298565b336000526002602052612aec60ff60406000205416611faa565b6040830194612b07612b00610f8688612893565b85356129f1565b612caf575b50505087612b34610d83999694610fc3610f86610fbd61274d9c9b9997612b6f973590612a3a565b612b50612b49610f866020610fde888a612846565b878a612855565b90612b5e610f318688612835565b90611011611009610f31888a612846565b612b8b611034611034610f31612b84856129fe565b8587612855565b6040516370a0823160e01b8082526001600160a01b03871660048301529096909491602090889060249082905afa968715612ca2575b600097612c57575b50611034610f318795602097956110c4612bf396612c189b6110be611034986110b636878961289d565b906040518095819482938352600483019190916001600160a01b036020820193169052565b03915afa908115612c4a575b600091612c315750612a3a565b61195c915060203d60201161099c5761098e8183610369565b612c5261213b565b612c24565b611034919750610f318795602097956110c4612bf396612c189b6110be612c8e611034988e3d60201161099c5761098e8183610369565b9e9850505096505095975095975050612bc9565b612caa61213b565b612bc1565b89612d9f916001600160a01b039c999795939b9a9896949c7f0000000000000000000000000000000000000000000000000000000000000000169b8c918b8b60405195888b6020896370a0823160e01b998a82528180612d2230600483019190916001600160a01b036020820193169052565b03915afa988915612ea2575b600099612e59575b5092612b50612d7293612d5f612d84999794612d58610f86612d799b99612893565b90356129f1565b9261102e610f866020610fde8a8c612846565b369161289d565b612536368c8f612971565b6040519081523060048201526020818d818060248101612c18565b92893b1561026257610fc3610f86610fbd8a95612b3495610d839f61274d9f612e0582612b6f9c612e0b9360006040518092632e1a7d4d60e01b8252818381612df088600483019190602083019252565b03925af18015612e4c575b612e3f5750612a3a565b32613ffe565b80612e24575b50975097999b9c50505050949699612b0c565b612e3990612e3460208401612873565b613ffe565b38612e11565b8061095b61195c92610339565b612e5461213b565b612dfb565b612d799694919950612d7293612d5f612d84999794612d58610f86612e8f612b509660203d60201161099c5761098e8183610369565b9e96999b50505094979950509350612d36565b612eaa61213b565b612d2e565b926102a79491612ed091846001600160a01b036020840151169251926137e7565b917f0000000000000000000000000000000000000000000000000000000000000000613f72565b15612efe57565b606460405162461bcd60e51b815260206004820152601860248201527f546f6164526f757465723a20494e56414c49445f5041544800000000000000006044820152fd5b96939891979094421115612f5590612298565b60009333855260209860028a52604086205460ff16612f7390611faa565b612f7c856129fe565b612f87908683612855565b612f9090612873565b7f0000000000000000000000000000000000000000000000000000000000000000996001600160a01b03808c169792612fcb91168814612ef7565b8c8c612fd78486612846565b01612fe190612893565b6bffffffffffffffffffffffff16612ffa908787612855565b6130048486612835565b61300d90612873565b6130178587612846565b61302090612873565b913661302b91612921565b61303494612eaf565b369061303f9261289d565b91369061304b92612971565b30613055926132e7565b6040516370a0823160e01b8152306004820152978789602481865afa948515996130b29a613245575b8596613226575b5061309287358097612a3a565b976130a76040890199610fc3610f868c612893565b9a8b92831015612a47565b831561321757506130c6866130d8926129f1565b6130d2610f868a612893565b906129f1565b833b1561198257604051632e1a7d4d60e01b81526004810191909152613115918a918681602481838a5af1801561320a575b6131f7575b50613ffe565b613124610f97610f8688612893565b613133575b5050505050505090565b15613186575b50506131459032613ffe565b6bffffffffffffffffffffffff61315b83612893565b1661316a575b80808080613129565b610f86610fbd61317e9461129e9301612873565b388080613161565b6131956111f5610f8687612893565b813b1561097157604051632e1a7d4d60e01b81526004810191909152613145939290918290602490829084905af180156131ea575b6131d7575b819250613139565b8061095b6131e492610339565b386131cf565b6131f261213b565b6131ca565b8061095b61320492610339565b3861310f565b61321261213b565b61310a565b9161322192613e89565b613115565b61323e919650893d8b1161099c5761098e8183610369565b9438613085565b61324d61213b565b61307e565b51906dffffffffffffffffffffffffffff8216820361026257565b908160609103126102625761328181613252565b91604061329060208401613252565b92015163ffffffff811681036102625790565b6040516132af8161034d565b60008152906000368137565b90610d8394936080936001600160a01b0392845260208401521660408201528160608201520190610d4d565b90929160005b6132f783516129fe565b811015613660576133088184611eec565b51516001600160a01b03169061331d816129cd565b6133279085611eec565b51516001600160a01b03169161333d838261370b565b5092602090818061334d866129cd565b613357908a611eec565b510151613372906bffffffffffffffffffffffff1688611eec565b5101516001600160a01b031683828461338a886129cd565b613394908c611eec565b5101516133af906bffffffffffffffffffffffff168a611eec565b5151916133bb936137e7565b6001600160a01b03166001600160a01b031660409283517f0902f1ac0000000000000000000000000000000000000000000000000000000081526060906004988183818c8095895afa61349f9461349a928215613653575b6000918293613620575b50506dffffffffffffffffffffffffffff8091169116996001600160a01b03809116931683149986888c600014613613576134819293958694975b8d518095819482936370a0823160e01b845283019190916001600160a01b036020820193169052565b03915afa908115613606575b6000916135ef5750612a3a565b613b2a565b94156135e5578886600096945b8a6134b78451612a0d565b8310156135d957613541610f86866134f161351482613505613547976134eb610f8661354f9e6134f18f8f6134eb906129e3565b90611eec565b5101516bffffffffffffffffffffffff1690565b5101516001600160a01b031690565b976134eb61353b61352d6135278b6129e3565b84611eec565b51516001600160a01b031690565b986129e3565b8c611eec565b5151926137e7565b935b6135596132a3565b823b15610262576135b49761359f60009692879351988997889687957f022c0d9f00000000000000000000000000000000000000000000000000000000875286016132bb565b03925af180156135cc575b6135b95750611d6d565b6132ed565b8061095b6135c692610339565b38610789565b6135d461213b565b6135aa565b50505050508993613551565b88866000946134ac565b61195c9150873d891161099c5761098e8183610369565b61360e61213b565b61348d565b6134819295869497613458565b613643935080919250903d1061364c575b61363b8183610369565b81019061326d565b5090388061341d565b503d613631565b61365b61213b565b613413565b5050509050565b604051906136748261031d565b60006020838281520152565b9061368a82610399565b6136976040519182610369565b828152601f196136a78294610399565b019060005b8281106136b857505050565b6020906136c3613667565b828285010152016136ac565b604051906136dc8261031d565b600182528160005b60209081811015613706576020916136fa613667565b908285010152016136e4565b505050565b90916001600160a01b039182841683821681811461377e57101561377957925b9183161561373557565b606460405162461bcd60e51b815260206004820152601d60248201527f546f6164737761704c6962726172793a205a45524f5f414444524553530000006044820152fd5b61372b565b608460405162461bcd60e51b8152602060048201526024808201527f546f6164737761704c6962726172793a204944454e544943414c5f414444524560448201527f53534553000000000000000000000000000000000000000000000000000000006064820152fd5b916137fb906001600160a01b03949261370b565b919060405160208101917fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009485809260601b16845260601b1660348201526028815261384681610301565b5190206040519260208401947fff00000000000000000000000000000000000000000000000000000000000000865260601b1660218401526035830152605582015260558152613895816102d8565b5190201690565b156138a357565b606460405162461bcd60e51b815260206004820152601d60248201527f546f6164737761704c6962726172793a20494e56414c49445f504154480000006044820152fd5b906138f182610399565b6138fe6040519182610369565b828152601f1961390e8294610399565b0190602036910137565b6060829161393f6004959661392d888661370b565b50976001600160a01b039586946137e7565b16604051948580927f0902f1ac0000000000000000000000000000000000000000000000000000000082525afa9283156139c6575b60009081946139a4575b5081906dffffffffffffffffffffffffffff80911694169416911614600014610b605791565b8294506139bf915060603d811161364c5761363b8183610369565b509361397e565b6139ce61213b565b613974565b156139da57565b608460405162461bcd60e51b815260206004820152602760248201527f546f6164737761704c6962726172793a20494e53554646494349454e545f4c4960448201527f51554944495459000000000000000000000000000000000000000000000000006064820152fd5b906103e5918281029281840414901517156129db57565b818102929181159184041417156129db57565b8115613a78570490565b634e487b7160e01b600052601260045260246000fd5b8015613ac157610d8392613ab39183151580613ab8575b613aae906139d3565b613a5b565b613a6e565b50811515613aa5565b608460405162461bcd60e51b8152602060048201526024808201527f546f6164737761704c6962726172793a20494e53554646494349454e545f414d60448201527f4f554e54000000000000000000000000000000000000000000000000000000006064820152fd5b91908215613ba557610d839281613b66613b7c931594851580613b9c575b613b51906139d3565b6103e580850294850403613b8f575b83613a5b565b936103e8808302928304141715613b82576129f1565b90613a6e565b613b8a611d56565b6129f1565b613b97611d56565b613b60565b50801515613b48565b608460405162461bcd60e51b815260206004820152602a60248201527f546f6164737761704c6962726172793a20494e53554646494349454e545f494e60448201527f5055545f414d4f554e54000000000000000000000000000000000000000000006064820152fd5b918215613c7357613b7c613c5384613c39610d839686613c5897151580613c6a57613aae906139d3565b936103e894858102958187041490151715613c5d57612a3a565b613a44565b6129cd565b613c65611d56565b612a3a565b50861515613aa5565b608460405162461bcd60e51b815260206004820152602b60248201527f546f6164737761704c6962726172793a20494e53554646494349454e545f4f5560448201527f545055545f414d4f554e540000000000000000000000000000000000000000006064820152fd5b929190613cee60028251101561389c565b613cf881516138e7565b93613d0285611ed6565b5260005b613d1082516129fe565b81101561370657613dad90613d95613d846020613d4981613505613d43610f86836134f1613d3d8b6129cd565b8d611eec565b8a611eec565b90613d5761352d8689611eec565b613d7c613d43610f86613d6f61352d613d3d8b6129cd565b946134f1613d3d8b6129cd565b515192613918565b90613d8f848a611eec565b51613b2a565b613da7613da1836129cd565b88611eec565b52611d6d565b613d06565b600019908015611d7d570190565b929190613dd160028251101561389c565b613ddb81516138e7565b93613def613de986516129fe565b86611eec565b52613dfa81516129fe565b805b613e0557505050565b613e8390613e71613e606020613e2981613505613d43610f86836134f18a8d611eec565b90613e3f61352d613e39876129fe565b89611eec565b613d7c613d43610f86613e5561352d8a8d611eec565b946134f18a8d611eec565b90613e6b848a611eec565b51613c0f565b613e7d613da1836129fe565b52613db2565b80613dfc565b60009291838093604051906001600160a01b0360208301947fa9059cbb000000000000000000000000000000000000000000000000000000008652166024830152604482015260448152613edc816102d8565b51925af1613ee8611e47565b81613f3a575b5015613ef657565b606460405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152fd5b8051801592508215613f4f575b505038613eee565b81925090602091810103126102625760200151613f6b81610a6e565b3880613f47565b91939092936001600160a01b0380931693843b156102625760009484869281608496816040519b8c9a8b997f36c78516000000000000000000000000000000000000000000000000000000008b521660048a01521660248801521660448601521660648401525af18015613ff1575b613fe85750565b6102a790610339565b613ff961213b565b613fe1565b60008080938193826040516140128161034d565b525af161401d611e47565b501561402557565b608460405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201527f4c454400000000000000000000000000000000000000000000000000000000006064820152fdfea26469706673582212209c3a44e2e70ef9ba9821ca2224474cb96d9d67da84ccf3621a5d6d1b599b777b64736f6c634300081100330000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3
Deployed Bytecode
0x60806040526004361015610023575b361561001957600080fd5b610021611f0e565b005b60003560e01c8063054d50d41461023f57806318232776146102365780631f00ca741461022d57806322aeedc314610224578063307ab24b1461021b57806331e7d53a146102125780634000120214610209578063412f845b14610200578063486ff0cd146101f757806350087bdf146101ee5780636652dd6d146101e5578063715018a6146101dc57806385f8c259146101d3578063880fbf0a146101ca5780638da5cb5b146101c15780638db7ac9a146101b85780638feca794146101af578063ac9650d8146101a6578063ad5c46481461019d578063ad615dec14610194578063b23c19e61461018b578063b43ba43114610182578063c09d54e514610179578063c45a015514610170578063d06ca61f14610167578063d83af6871461015e5763f2fde38b0361000e57610159611bc0565b61000e565b50610159611b74565b50610159611aaa565b50610159611a65565b506101596119cf565b50610159611986565b50610159611820565b50610159611806565b506101596117c1565b506101596116bf565b5061015961161e565b50610159611597565b5061015961156f565b506101596114d6565b506101596114bc565b50610159611447565b506101596112cf565b50610159610e8d565b50610159610d86565b50610159610cf3565b50610159610cb7565b50610159610b64565b50610159610a78565b506101596107d2565b50610159610691565b506101596104c1565b50610159610267565b600319606091011261026257600435906024359060443590565b600080fd5b503461026257602061028161027b36610248565b91613b2a565b604051908152f35b6001600160a01b0381160361026257565b606435906102a782610289565b565b608435906102a782610289565b35906102a782610289565b50634e487b7160e01b600052604160045260246000fd5b6080810190811067ffffffffffffffff8211176102f457604052565b6102fc6102c1565b604052565b6060810190811067ffffffffffffffff8211176102f457604052565b6040810190811067ffffffffffffffff8211176102f457604052565b67ffffffffffffffff81116102f457604052565b6020810190811067ffffffffffffffff8211176102f457604052565b90601f601f19910116810190811067ffffffffffffffff8211176102f457604052565b604051906102a78261031d565b60209067ffffffffffffffff81116103b3575b60051b0190565b6103bb6102c1565b6103ac565b359065ffffffffffff8216820361026257565b602319608091011261026257604051906103ec826102d8565b816024356103f981610289565b815260443561040781610289565b602082015265ffffffffffff90606435828116810361026257604082015260843591821682036102625760600152565b91908260809103126102625760405161044f816102d8565b606061048e818395803561046281610289565b8552602081013561047281610289565b6020860152610483604082016103c0565b6040860152016103c0565b910152565b9181601f840112156102625782359167ffffffffffffffff8311610262576020838186019501011161026257565b503461026257600319606081360112610262576004356104e081610289565b6024359067ffffffffffffffff92838311610262576060908336030112610262576040519161050e83610301565b8060040135848111610262578101366023820112156102625760048101359061053682610399565b906105446040519283610369565b82825260209260248484019160071b8301019136831161026257602401905b8282106105ad5750505084526044919061057f602483016102b6565b9085015201356040830152604435928311610262576105a5610021933690600401610493565b929091612148565b846080916105bb3685610437565b815201910190610563565b906040600319830112610262576004359160243567ffffffffffffffff811161026257816023820112156102625780600401359161060383610399565b926106116040519485610369565b80845260209260248486019260051b82010192831161026257602401905b82821061063d575050505090565b838091833561064b81610289565b81520191019061062f565b6020908160408183019282815285518094520193019160005b82811061067d575050505090565b83518552938101939281019260010161066f565b5034610262576106a0366105c6565b906106ab8251613680565b916106b46136cf565b604051916106c18361031d565b7f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f83526020926001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f168482015261071e83611ed6565b5261072882611ed6565b50600091825b8251811015610794578061075561074861078f9386611eec565b516001600160a01b031690565b61076f61076061038c565b6001600160a01b039092168252565b858782015261077e828a611eec565b526107898189611eec565b50611d6d565b61072e565b6107ae6107a2838989613dc0565b60405191829182610656565b0390f35b6084359060ff8216820361026257565b6064359060ff8216820361026257565b50346102625760e0600319360112610262576001600160a01b036004356107f881610289565b60243561080481610289565b61080c6107b2565b6000938492338452600260205261082960ff604086205416611faa565b166108947fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6040517f30adf81f00000000000000000000000000000000000000000000000000000000815260208160048189885af19081156109a3575b8691610975575b501461233d565b803b15610971576040517f8fcbaf0c0000000000000000000000000000000000000000000000000000000081526001600160a01b0394851660048201527f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3949094166024850152604480359085015260648035908501526001608485015260ff90911660a4808501919091523560c4808501919091523560e4840152829081838161010481015b03925af18015610964575b61094e575080f35b8061095b61096192610339565b80610cac565b80f35b61096c61213b565b610946565b8280fd5b610996915060203d811161099c575b61098e8183610369565b81019061232e565b3861088d565b503d610984565b6109ab61213b565b610886565b9181601f840112156102625782359167ffffffffffffffff8311610262576020808501948460061b01011161026257565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5c60609101126102625760a490565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc606091011261026257604490565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c60609101126102625760c490565b8015150361026257565b5034610262576101406003193601126102625767ffffffffffffffff60443581811161026257610aac9036906004016109b0565b6064359291610aba84610289565b610ac3366109e1565b9361010435938411610262576107ae94610ae4610b049536906004016109b0565b9390926101243595610af587610a6e565b60843592602435600435612f42565b6040519081529081906020820190565b906060600319830112610262576004359167ffffffffffffffff916024358381116102625782610b46916004016109b0565b9390939260443591821161026257610b60916004016109b0565b9091565b503461026257610b7336610b14565b91610b8560028296959396101561389c565b610b8e816138e7565b93610b9885611ed6565b5260005b610ba5826129fe565b811015610c9e5760208080610bb9846129cd565b610bc4908688612855565b01610bce90612893565b6bffffffffffffffffffffffff16610be790878a612855565b01610bf190612873565b90610bfd838587612855565b610c0690612873565b90610c10846129cd565b610c1b908688612855565b610c2490612873565b90610c2e856129cd565b610c39908789612855565b01610c4390612893565b6bffffffffffffffffffffffff16610c5c90888b612855565b3591610c6793613918565b610c718388611eec565b5191610c7c92613a8e565b610c85826129cd565b610c8f9087611eec565b52610c9990611d6d565b610b9c565b604051806107ae8782610656565b600091031261026257565b50346102625760006003193601126102625760206040517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb8152f35b5034610262576107ae6107a2610d1c610d24610d0e36610b14565b94939591929092369161289d565b923691612971565b91613dc0565b60005b838110610d3d5750506000910152565b8181015183820152602001610d2d565b90601f19601f602093610d6b81518092818752878088019101610d2a565b0116010190565b906020610d83928181520190610d4d565b90565b503461026257600080600319360112610e8a57604051908080549060019180831c92808216928315610e80575b6020928386108514610e6c578588526020880194908115610e4b5750600114610df3575b6107ae87610de781890382610369565b60405191829182610d72565b6000805294509192917f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b838610610e3a5750505091019050610de7826107ae3880610dd7565b805485870152948201948101610e1e565b60ff191685525050505090151560051b019050610de7826107ae3880610dd7565b602482634e487b7160e01b81526022600452fd5b93607f1693610db3565b80fd5b5034610262576101206003193601126102625760443567ffffffffffffffff80821161026257610ec2600492369084016109b0565b909260643591610ed183610289565b610eda366109e1565b936101043590811161026257610ef390369084016109b0565b610f04949194426084351015612298565b60009333855260209360028552604097610f2360ff8a89205416611faa565b84610f36610f31848d612835565b612873565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2926001600160a01b0380851692610f7091168314612ef7565b8035918c820194610f9d610f97610f8688612893565b6bffffffffffffffffffffffff1690565b856129f1565b61119f575b50505061101792610fc3610f86610fbd610fc9948935612a3a565b92612893565b90612a3a565b8b610feb610fe4610f868b610fde8986612846565b01612893565b888d612855565b91611011611009610f3188611003610f318288612835565b95612846565b933690612921565b90612eaf565b611040611034611034610f318c8561102e816129fe565b91612855565b6001600160a01b031690565b9288519786896370a0823160e01b9687825281806110708b8a83019190916001600160a01b036020820193169052565b03915afa988915611192575b8899611150575b50926110cd611034611034610f316107ae9e8a976110c46111099f9e9d9b986110f09d6110be8e9d6110b636878961289d565b933691612971565b916132e7565b61102e816129fe565b918a5196879485938493845283019190916001600160a01b036020820193169052565b03915afa928315611143575b92611126575b5050612a3a565b90611118602435831015612a47565b519081529081906020820190565b61113c9250803d1061099c5761098e8183610369565b3880611102565b61114b61213b565b6110fc565b86939950958795929686959299983d871161118b575b6111708183610369565b810161117b9161232e565b9993969295509790939697611083565b503d611166565b61119a61213b565b61107c565b6111e691929394506111bc6111b6610f8688612893565b866129f1565b908a30917f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3613f72565b6111fb6111f5610f8686612893565b846129f1565b90803b156112cb57610f86610fbd8a958f610fc9968f8f92906110179b98610fc3988f836112409551809681958294632e1a7d4d60e01b845283019190602083019252565b03925af180156112be575b6112ab575b5061125b8332613ffe565b6bffffffffffffffffffffffff61127188612893565b16611284575b5050945050829550610fa2565b6112a4916112929101612873565b61129e610f8688612893565b90613ffe565b8c38611277565b8061095b6112b892610339565b38611250565b6112c661213b565b61124b565b8a80fd5b50346102625760c0600319360112610262576001600160a01b036004356112f581610289565b60243561130181610289565b60443561130c6107c2565b9261131942831015612298565b6000948593338552600260205261133660ff604087205416611faa565b6040517f7ecebe0000000000000000000000000000000000000000000000000000000000602082019081526001600160a01b038516602480840191909152825261139d9187918291611389604482610369565b519082865af1611397611e47565b506122e3565b1690813b15611443576040517fd505accf0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201527f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba39190911660248201526000196044820152606481019290925260ff9093166084808301919091523560a4808301919091523560c482015291829081838160e4810161093b565b8380fd5b503461026257600080600319360112610e8a57611462611cb5565b806001600160a01b036001547fffffffffffffffffffffffff00000000000000000000000000000000000000008116600155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b50346102625760206102816114d036610248565b91613c0f565b5034610262576101606003193601126102625767ffffffffffffffff6044358181116102625761150a9036906004016109b0565b919061151461029a565b61151d366109e1565b9361012435848111610262576115379036906004016109b0565b9161014435958611610262576107ae96611558610b049736906004016109b0565b969095610104359360843592602435600435612ab8565b50346102625760006003193601126102625760206001600160a01b0360015416604051908152f35b503461026257610100600319360112610262576004356115b681610289565b60c0602319360112610262576040516115ce81610301565b6115d7366103d3565b815260a4356115e581610289565b602082015260c435604082015260e4359167ffffffffffffffff831161026257611616610021933690600401610493565b929091611ff5565b5034610262576107ae6107a2610d1c611639610d0e36610b14565b91613cdd565b602080820190808352835180925260408301928160408460051b8301019501936000915b8483106116735750505050505090565b90919293949584806116af837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc086600196030187528a51610d4d565b9801930193019194939290611663565b506020600319360112610262576004803567ffffffffffffffff918282116102625736602383011215610262578181013592831161026257602490818301928236918660051b0101116102625761171584611d0d565b9360005b81811061172e57604051806107ae888261163f565b60008061173c838589611da0565b6040939161174e855180938193611e0e565b0390305af49061175c611e47565b9182901561178557505090611780916117758289611eec565b526107898188611eec565b611719565b86838792604482511061026257826117bd93856117a89401518301019101611e77565b925192839262461bcd60e51b84528301610d72565b0390fd5b50346102625760006003193601126102625760206040516001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2168152f35b503461026257602061028161181a36610248565b91613a8e565b50346102625760a06003193601126102625760043561183e81610289565b6024359061184b36610a10565b90600092338452600260205261186760ff604086205416611faa565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26118bd833086847f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3613f72565b1692833b1561198257610fc3610f86610fbd61129e9461096197896040518092632e1a7d4d60e01b82528183816118fc88600483019190602083019252565b03925af18015611975575b611962575b5084359061191a8232613ffe565b60408601956bffffffffffffffffffffffff61193588612893565b16611941575b50612a3a565b611950602061195c9201612873565b61129e610f8689612893565b3861193b565b8061095b61196f92610339565b3861190c565b61197d61213b565b611907565b8480fd5b5034610262576020600319360112610262576001600160a01b036004356119ac81610289565b6119b4611cb5565b166000526002602052604060002060ff198154169055600080f35b5034610262576101406003193601126102625767ffffffffffffffff60443581811161026257611a039036906004016109b0565b919060643582811161026257611a1d9036906004016109b0565b939091611a286102a9565b90611a3236610a3f565b9161012435958611610262576107ae96611a53610b049736906004016109b0565b96909560a435946024356004356123ae565b50346102625760006003193601126102625760206040516001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f168152f35b503461026257611ab9366105c6565b90611ac48251613680565b91611acd6136cf565b60405191611ada8361031d565b7f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f83526020926001600160a01b037f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f1684820152611b3783611ed6565b52611b4182611ed6565b50600091825b8251811015611b665780610755610748611b619386611eec565b611b47565b6107ae6107a2838989613cdd565b5034610262576020600319360112610262576001600160a01b03600435611b9a81610289565b611ba2611cb5565b1660005260026020526040600020600160ff19825416179055600080f35b503461026257602060031936011261026257600435611bde81610289565b611be6611cb5565b6001600160a01b03809116908115611c4b57600154827fffffffffffffffffffffffff0000000000000000000000000000000000000000821617600155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b608460405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b6001600160a01b03600154163303611cc957565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b90611d1782610399565b611d246040519182610369565b828152601f19611d348294610399565b019060005b828110611d4557505050565b806060602080938501015201611d39565b50634e487b7160e01b600052601160045260246000fd5b6001906000198114611d7d570190565b611d85611d56565b0190565b50634e487b7160e01b600052603260045260246000fd5b9190811015611e01575b60051b810135907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18136030182121561026257019081359167ffffffffffffffff8311610262576020018236038113610262579190565b611e09611d89565b611daa565b908092918237016000815290565b601f19601f60209267ffffffffffffffff8111611e3a575b01160190565b611e426102c1565b611e34565b3d15611e72573d90611e5882611e1c565b91611e666040519384610369565b82523d6000602084013e565b606090565b6020818303126102625780519067ffffffffffffffff8211610262570181601f82011215610262578051611eaa81611e1c565b92611eb86040519485610369565b8184526020828401011161026257610d839160208085019101610d2a565b602090805115611ee4570190565b611d85611d89565b6020918151811015611f01575b60051b010190565b611f09611d89565b611ef9565b6001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2163303611f4057565b608460405162461bcd60e51b815260206004820152602160248201527f546f6164526f757465723a204e6f20455448206e6f742066726f6d205745544860448201527f2e000000000000000000000000000000000000000000000000000000000000006064820152fd5b15611fb157565b606460405162461bcd60e51b815260206004820152601560248201527f546f6164526f757465723a20554e5452555354454400000000000000000000006044820152fd5b919092600092338452600260205261201360ff604086205416611faa565b6001600160a01b0392837f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31692833b1561211657916120ea86928694604080519a8b998a9889977f2b67b5700000000000000000000000000000000000000000000000000000000089521660048801526120c56024880183516060906001600160a01b0380825116845260208201511660208401528165ffffffffffff91826040820151166040860152015116910152565b60208201511660a4870152015160c485015261010060e485015261010484019161211a565b03925af18015612109575b6120fc5750565b8061095b6102a792610339565b61211161213b565b6120f5565b8580fd5b601f8260209493601f19938186528686013760008582860101520116010190565b506040513d6000823e3d90fd5b92916000923384526020916002835261216760ff604087205416611faa565b6001600160a01b0393847f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba31694853b15612294579694939186939188604051998a987f2a2d80d1000000000000000000000000000000000000000000000000000000008a521660048901526060602489015260c4880194825195606060648b015286518091528160e48b01970190885b81811061222d575050508201511660848801526040015160a487015285830360031901604487015285939284926120ea9261211a565b929496985092949681999a5060808161227e8793600195516060906001600160a01b0380825116845260208201511660208401528165ffffffffffff91826040820151166040860152015116910152565b0199019101908b99989694928b989694926121f7565b8680fd5b1561229f57565b606460405162461bcd60e51b815260206004820152601360248201527f546f6164526f757465723a2045585049524544000000000000000000000000006044820152fd5b156122ea57565b606460405162461bcd60e51b815260206004820152601e60248201527f546f6164526f7574657230333a204e6f74205065726d69747461626c652e00006044820152fd5b90816020910312610262575190565b1561234457565b608460405162461bcd60e51b815260206004820152602360248201527f546f6164526f7574657230333a204e6f74204461692d7374796c65205065726d60448201527f69742e00000000000000000000000000000000000000000000000000000000006064820152fd5b9398979296999099959491954211156123c690612298565b60009633885260209660028852604095868a205460ff166123e690611faa565b6123f08383612835565b6123f990612873565b90898c86826124088888612846565b0161241290612893565b6bffffffffffffffffffffffff169061242a92612855565b0161243490612873565b8c8b6124408787612835565b61244990612873565b91886124558989612846565b61245e90612873565b926124698a8a612846565b0161247390612893565b6bffffffffffffffffffffffff169061248b92612855565b3591612496936137e7565b897f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3936124c294613f72565b85516370a0823160e01b8082523060048301529590927f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316918a85602481865afa948515612828575b8c95612809575b5061253e8d61253661252d36868961289d565b91893691612971565b9030906132e7565b88810190612558612551610f8684612893565b82356129f1565b843b15612805578f93919289938f8f939061258b918f5180938192632e1a7d4d60e01b8352600483019190602083019252565b0381838c5af180156127f8575b6127e5575b506125a9813532613ffe565b6bffffffffffffffffffffffff6125bf83612893565b166127c9575b5050878f916125d48587612835565b6125dd90612873565b9781806125ea888a612846565b016125f490612893565b6bffffffffffffffffffffffff1661260d908587612855565b0161261790612873565b966126228782612835565b61262b90612873565b9661263591612846565b61263e90612873565b9461264891612846565b0161265290612893565b6bffffffffffffffffffffffff169061266a92612855565b3591612675936137e7565b875187815230600482015290918a90829060249082905afa938415946126aa926126b0966127bc575b8d916127a55750612a3a565b91613e89565b6126c7611034611034610f318c8661102e816129fe565b84518481526001600160a01b0387166004820152989087908a9060249082905afa988915612798575b8899612756575b509261272a611034611034610f31610d839d8a976110c461274d9f9e9d9b986110f09d6110be8e9d6110b636878961289d565b91518096819482938352600483019190916001600160a01b036020820193169052565b91821015612a47565b86939950958795929686959299983d8711612791575b6127768183610369565b81016127819161232e565b99939692955097909396976126f7565b503d61276c565b6127a061213b565b6126f0565b61195c91508c8d3d1061099c5761098e8183610369565b6127c461213b565b61269e565b610f86610fbd6127dd9461129e9301612873565b8b38806125c5565b8061095b6127f292610339565b3861259d565b61280061213b565b612598565b8d80fd5b6128219195508b3d8d1161099c5761098e8183610369565b933861251a565b61283061213b565b612513565b901561283e5790565b610d83611d89565b60409160011015611ee4570190565b9190811015612866575b60061b0190565b61286e611d89565b61285f565b35610d8381610289565b6bffffffffffffffffffffffff81160361026257565b35610d838161287d565b9291926128a982610399565b6040926128b884519283610369565b819581835260208093019160061b84019381851161026257915b8483106128e157505050505050565b85838303126102625783869182516128f88161031d565b853561290381610289565b8152828601356129128161287d565b838201528152019201916128d2565b9190826040910312610262576040516040810181811067ffffffffffffffff821117612964575b60405260208082948035845201359161296083610289565b0152565b61296c6102c1565b612948565b92919261297d82610399565b60409261298c84519283610369565b819581835260208093019160061b84019381851161026257915b8483106129b557505050505050565b8386916129c28486612921565b8152019201916129a6565b90600182018092116129db57565b6102a7611d56565b90600282018092116129db57565b919082018092116129db57565b9060001982019182116129db57565b907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe82019182116129db57565b919082039182116129db57565b15612a4e57565b608460405162461bcd60e51b815260206004820152602660248201527f546f6164526f757465723a20494e53554646494349454e545f4f55545055545f60448201527f414d4f554e5400000000000000000000000000000000000000000000000000006064820152fd5b93999894612ad2909b98919b979297969396421115612298565b336000526002602052612aec60ff60406000205416611faa565b6040830194612b07612b00610f8688612893565b85356129f1565b612caf575b50505087612b34610d83999694610fc3610f86610fbd61274d9c9b9997612b6f973590612a3a565b612b50612b49610f866020610fde888a612846565b878a612855565b90612b5e610f318688612835565b90611011611009610f31888a612846565b612b8b611034611034610f31612b84856129fe565b8587612855565b6040516370a0823160e01b8082526001600160a01b03871660048301529096909491602090889060249082905afa968715612ca2575b600097612c57575b50611034610f318795602097956110c4612bf396612c189b6110be611034986110b636878961289d565b906040518095819482938352600483019190916001600160a01b036020820193169052565b03915afa908115612c4a575b600091612c315750612a3a565b61195c915060203d60201161099c5761098e8183610369565b612c5261213b565b612c24565b611034919750610f318795602097956110c4612bf396612c189b6110be612c8e611034988e3d60201161099c5761098e8183610369565b9e9850505096505095975095975050612bc9565b612caa61213b565b612bc1565b89612d9f916001600160a01b039c999795939b9a9896949c7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2169b8c918b8b60405195888b6020896370a0823160e01b998a82528180612d2230600483019190916001600160a01b036020820193169052565b03915afa988915612ea2575b600099612e59575b5092612b50612d7293612d5f612d84999794612d58610f86612d799b99612893565b90356129f1565b9261102e610f866020610fde8a8c612846565b369161289d565b612536368c8f612971565b6040519081523060048201526020818d818060248101612c18565b92893b1561026257610fc3610f86610fbd8a95612b3495610d839f61274d9f612e0582612b6f9c612e0b9360006040518092632e1a7d4d60e01b8252818381612df088600483019190602083019252565b03925af18015612e4c575b612e3f5750612a3a565b32613ffe565b80612e24575b50975097999b9c50505050949699612b0c565b612e3990612e3460208401612873565b613ffe565b38612e11565b8061095b61195c92610339565b612e5461213b565b612dfb565b612d799694919950612d7293612d5f612d84999794612d58610f86612e8f612b509660203d60201161099c5761098e8183610369565b9e96999b50505094979950509350612d36565b612eaa61213b565b612d2e565b926102a79491612ed091846001600160a01b036020840151169251926137e7565b917f000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3613f72565b15612efe57565b606460405162461bcd60e51b815260206004820152601860248201527f546f6164526f757465723a20494e56414c49445f5041544800000000000000006044820152fd5b96939891979094421115612f5590612298565b60009333855260209860028a52604086205460ff16612f7390611faa565b612f7c856129fe565b612f87908683612855565b612f9090612873565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2996001600160a01b03808c169792612fcb91168814612ef7565b8c8c612fd78486612846565b01612fe190612893565b6bffffffffffffffffffffffff16612ffa908787612855565b6130048486612835565b61300d90612873565b6130178587612846565b61302090612873565b913661302b91612921565b61303494612eaf565b369061303f9261289d565b91369061304b92612971565b30613055926132e7565b6040516370a0823160e01b8152306004820152978789602481865afa948515996130b29a613245575b8596613226575b5061309287358097612a3a565b976130a76040890199610fc3610f868c612893565b9a8b92831015612a47565b831561321757506130c6866130d8926129f1565b6130d2610f868a612893565b906129f1565b833b1561198257604051632e1a7d4d60e01b81526004810191909152613115918a918681602481838a5af1801561320a575b6131f7575b50613ffe565b613124610f97610f8688612893565b613133575b5050505050505090565b15613186575b50506131459032613ffe565b6bffffffffffffffffffffffff61315b83612893565b1661316a575b80808080613129565b610f86610fbd61317e9461129e9301612873565b388080613161565b6131956111f5610f8687612893565b813b1561097157604051632e1a7d4d60e01b81526004810191909152613145939290918290602490829084905af180156131ea575b6131d7575b819250613139565b8061095b6131e492610339565b386131cf565b6131f261213b565b6131ca565b8061095b61320492610339565b3861310f565b61321261213b565b61310a565b9161322192613e89565b613115565b61323e919650893d8b1161099c5761098e8183610369565b9438613085565b61324d61213b565b61307e565b51906dffffffffffffffffffffffffffff8216820361026257565b908160609103126102625761328181613252565b91604061329060208401613252565b92015163ffffffff811681036102625790565b6040516132af8161034d565b60008152906000368137565b90610d8394936080936001600160a01b0392845260208401521660408201528160608201520190610d4d565b90929160005b6132f783516129fe565b811015613660576133088184611eec565b51516001600160a01b03169061331d816129cd565b6133279085611eec565b51516001600160a01b03169161333d838261370b565b5092602090818061334d866129cd565b613357908a611eec565b510151613372906bffffffffffffffffffffffff1688611eec565b5101516001600160a01b031683828461338a886129cd565b613394908c611eec565b5101516133af906bffffffffffffffffffffffff168a611eec565b5151916133bb936137e7565b6001600160a01b03166001600160a01b031660409283517f0902f1ac0000000000000000000000000000000000000000000000000000000081526060906004988183818c8095895afa61349f9461349a928215613653575b6000918293613620575b50506dffffffffffffffffffffffffffff8091169116996001600160a01b03809116931683149986888c600014613613576134819293958694975b8d518095819482936370a0823160e01b845283019190916001600160a01b036020820193169052565b03915afa908115613606575b6000916135ef5750612a3a565b613b2a565b94156135e5578886600096945b8a6134b78451612a0d565b8310156135d957613541610f86866134f161351482613505613547976134eb610f8661354f9e6134f18f8f6134eb906129e3565b90611eec565b5101516bffffffffffffffffffffffff1690565b5101516001600160a01b031690565b976134eb61353b61352d6135278b6129e3565b84611eec565b51516001600160a01b031690565b986129e3565b8c611eec565b5151926137e7565b935b6135596132a3565b823b15610262576135b49761359f60009692879351988997889687957f022c0d9f00000000000000000000000000000000000000000000000000000000875286016132bb565b03925af180156135cc575b6135b95750611d6d565b6132ed565b8061095b6135c692610339565b38610789565b6135d461213b565b6135aa565b50505050508993613551565b88866000946134ac565b61195c9150873d891161099c5761098e8183610369565b61360e61213b565b61348d565b6134819295869497613458565b613643935080919250903d1061364c575b61363b8183610369565b81019061326d565b5090388061341d565b503d613631565b61365b61213b565b613413565b5050509050565b604051906136748261031d565b60006020838281520152565b9061368a82610399565b6136976040519182610369565b828152601f196136a78294610399565b019060005b8281106136b857505050565b6020906136c3613667565b828285010152016136ac565b604051906136dc8261031d565b600182528160005b60209081811015613706576020916136fa613667565b908285010152016136e4565b505050565b90916001600160a01b039182841683821681811461377e57101561377957925b9183161561373557565b606460405162461bcd60e51b815260206004820152601d60248201527f546f6164737761704c6962726172793a205a45524f5f414444524553530000006044820152fd5b61372b565b608460405162461bcd60e51b8152602060048201526024808201527f546f6164737761704c6962726172793a204944454e544943414c5f414444524560448201527f53534553000000000000000000000000000000000000000000000000000000006064820152fd5b916137fb906001600160a01b03949261370b565b919060405160208101917fffffffffffffffffffffffffffffffffffffffff0000000000000000000000009485809260601b16845260601b1660348201526028815261384681610301565b5190206040519260208401947fff00000000000000000000000000000000000000000000000000000000000000865260601b1660218401526035830152605582015260558152613895816102d8565b5190201690565b156138a357565b606460405162461bcd60e51b815260206004820152601d60248201527f546f6164737761704c6962726172793a20494e56414c49445f504154480000006044820152fd5b906138f182610399565b6138fe6040519182610369565b828152601f1961390e8294610399565b0190602036910137565b6060829161393f6004959661392d888661370b565b50976001600160a01b039586946137e7565b16604051948580927f0902f1ac0000000000000000000000000000000000000000000000000000000082525afa9283156139c6575b60009081946139a4575b5081906dffffffffffffffffffffffffffff80911694169416911614600014610b605791565b8294506139bf915060603d811161364c5761363b8183610369565b509361397e565b6139ce61213b565b613974565b156139da57565b608460405162461bcd60e51b815260206004820152602760248201527f546f6164737761704c6962726172793a20494e53554646494349454e545f4c4960448201527f51554944495459000000000000000000000000000000000000000000000000006064820152fd5b906103e5918281029281840414901517156129db57565b818102929181159184041417156129db57565b8115613a78570490565b634e487b7160e01b600052601260045260246000fd5b8015613ac157610d8392613ab39183151580613ab8575b613aae906139d3565b613a5b565b613a6e565b50811515613aa5565b608460405162461bcd60e51b8152602060048201526024808201527f546f6164737761704c6962726172793a20494e53554646494349454e545f414d60448201527f4f554e54000000000000000000000000000000000000000000000000000000006064820152fd5b91908215613ba557610d839281613b66613b7c931594851580613b9c575b613b51906139d3565b6103e580850294850403613b8f575b83613a5b565b936103e8808302928304141715613b82576129f1565b90613a6e565b613b8a611d56565b6129f1565b613b97611d56565b613b60565b50801515613b48565b608460405162461bcd60e51b815260206004820152602a60248201527f546f6164737761704c6962726172793a20494e53554646494349454e545f494e60448201527f5055545f414d4f554e54000000000000000000000000000000000000000000006064820152fd5b918215613c7357613b7c613c5384613c39610d839686613c5897151580613c6a57613aae906139d3565b936103e894858102958187041490151715613c5d57612a3a565b613a44565b6129cd565b613c65611d56565b612a3a565b50861515613aa5565b608460405162461bcd60e51b815260206004820152602b60248201527f546f6164737761704c6962726172793a20494e53554646494349454e545f4f5560448201527f545055545f414d4f554e540000000000000000000000000000000000000000006064820152fd5b929190613cee60028251101561389c565b613cf881516138e7565b93613d0285611ed6565b5260005b613d1082516129fe565b81101561370657613dad90613d95613d846020613d4981613505613d43610f86836134f1613d3d8b6129cd565b8d611eec565b8a611eec565b90613d5761352d8689611eec565b613d7c613d43610f86613d6f61352d613d3d8b6129cd565b946134f1613d3d8b6129cd565b515192613918565b90613d8f848a611eec565b51613b2a565b613da7613da1836129cd565b88611eec565b52611d6d565b613d06565b600019908015611d7d570190565b929190613dd160028251101561389c565b613ddb81516138e7565b93613def613de986516129fe565b86611eec565b52613dfa81516129fe565b805b613e0557505050565b613e8390613e71613e606020613e2981613505613d43610f86836134f18a8d611eec565b90613e3f61352d613e39876129fe565b89611eec565b613d7c613d43610f86613e5561352d8a8d611eec565b946134f18a8d611eec565b90613e6b848a611eec565b51613c0f565b613e7d613da1836129fe565b52613db2565b80613dfc565b60009291838093604051906001600160a01b0360208301947fa9059cbb000000000000000000000000000000000000000000000000000000008652166024830152604482015260448152613edc816102d8565b51925af1613ee8611e47565b81613f3a575b5015613ef657565b606460405162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c4544006044820152fd5b8051801592508215613f4f575b505038613eee565b81925090602091810103126102625760200151613f6b81610a6e565b3880613f47565b91939092936001600160a01b0380931693843b156102625760009484869281608496816040519b8c9a8b997f36c78516000000000000000000000000000000000000000000000000000000008b521660048a01521660248801521660448601521660648401525af18015613ff1575b613fe85750565b6102a790610339565b613ff961213b565b613fe1565b60008080938193826040516140128161034d565b525af161401d611e47565b501561402557565b608460405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201527f4c454400000000000000000000000000000000000000000000000000000000006064820152fdfea26469706673582212209c3a44e2e70ef9ba9821ca2224474cb96d9d67da84ccf3621a5d6d1b599b777b64736f6c63430008110033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3
-----Decoded View---------------
Arg [0] : fac (address): 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f
Arg [1] : weth (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [2] : permit (address): 0x000000000022D473030F116dDEE9F6B43aC78BA3
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.