Source Code
Overview
S Balance
0 S
More Info
ContractCreator
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
5091038 | 11 hrs ago | 0 S |
Loading...
Loading
Contract Name:
FarmZapper
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 800 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPLv2 // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // @author Wivern for Beefy.Finance // @notice This contract adds liquidity to Uniswap V2 compatible liquidity pair pools and stake. pragma solidity >=0.8.4; import "openzeppelin/access/Ownable.sol"; import {SafeERC20, IERC20} from "openzeppelin/token/ERC20/utils/SafeERC20.sol"; import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol"; import "./interfaces/IMagicSeaPair.sol"; import "./interfaces/IMagicSeaRouter02.sol"; import "./interfaces/IWNATIVE.sol"; import "./interfaces/IMasterChef.sol"; /** * @dev FarmZapper let's you directly zap-in into a farm * * Inspired by Beefy's beefyUniswapZap */ contract FarmZapper is Ownable { using SafeERC20 for IERC20; IMagicSeaRouter02 private immutable _router; IMasterChef private immutable _masterChef; address private immutable _wNative; uint256 private immutable _minimumAmount; event SwapAndStaked(uint256 indexed pid, address indexed tokenIn, uint256 amountLiquidity, address sender); constructor(address router, address masterchef, address wNative, uint256 minimumAmount, address admin) Ownable(admin) { require(IMagicSeaRouter02(router).WETH() == wNative, "FarmZapper: wNative address not matching Router.WETH()"); _router = IMagicSeaRouter02(router); _masterChef = IMasterChef(masterchef); _wNative = wNative; _minimumAmount = minimumAmount; } // EXTERNAL PAYABLE FUNCTIONS receive() external payable { assert(msg.sender == _wNative); } /** * @dev Zap in native token (WNATIVE) to a given pool pid */ function zapInWNative(uint256 pid, uint256 tokenAmountOutMin) external payable { require(msg.value >= _minimumAmount, "FarmZapper: Insignificant input amount"); IWNATIVE(_wNative).deposit{value: msg.value}(); _swapAndStake(pid, tokenAmountOutMin, _wNative); } // EXTERNAL FUNCTIONS /** * @dev Zap in a ERC20 token to a given pid, amount and amountOutMin */ function zapIn(uint256 pid, uint256 tokenAmountOutMin, address tokenIn, uint256 tokenInAmount) external { require(tokenInAmount >= _minimumAmount, "FarmZapper: Insignificant input amount"); require( IERC20(tokenIn).allowance(msg.sender, address(this)) >= tokenInAmount, "Beefy: Input token is not approved" ); IERC20(tokenIn).safeTransferFrom(msg.sender, address(this), tokenInAmount); _swapAndStake(pid, tokenAmountOutMin, tokenIn); } /** * @dev Zap out from LP Token. Burns the LP and return both assets of the given pair */ function zapOut(address lpToken, uint256 withdrawAmount, uint256 amountOutAMin, uint256 amountOutBMin) external { IMagicSeaPair pair = _getPair(lpToken); IERC20(lpToken).safeTransferFrom(msg.sender, address(this), withdrawAmount); uint256 amount0; uint256 amount1; if (pair.token0() != _wNative && pair.token1() != _wNative) { (amount0, amount1) = _removeLiquidity(address(pair), msg.sender); require(amount0 >= amountOutAMin, "MagicSeaRouter: INSUFFICIENT_A_AMOUNT"); require(amount1 >= amountOutBMin, "MagicSeaRouter: INSUFFICIENT_B_AMOUNT"); return; } (amount0, amount1) = _removeLiquidity(address(pair), address(this)); require(amount0 >= amountOutAMin, "MagicSeaRouter: INSUFFICIENT_A_AMOUNT"); require(amount1 >= amountOutBMin, "MagicSeaRouter: INSUFFICIENT_B_AMOUNT"); address[] memory tokens = new address[](2); tokens[0] = pair.token0(); tokens[1] = pair.token1(); _returnAssets(tokens); } /** * @dev Zap out from LP Token and swap it to a destination token of the given pair */ function zapOutAndSwap(address lpToken, uint256 withdrawAmount, address desiredToken, uint256 desiredTokenOutMin) external { IMagicSeaPair pair = _getPair(lpToken); address token0 = pair.token0(); address token1 = pair.token1(); require( token0 == desiredToken || token1 == desiredToken, "FarmZapper: desired token not present in liquidity pair" ); IERC20(lpToken).safeTransferFrom(msg.sender, address(this), withdrawAmount); _removeLiquidity(address(pair), address(this)); address swapToken = token1 == desiredToken ? token0 : token1; address[] memory path = new address[](2); path[0] = swapToken; path[1] = desiredToken; _approveTokenIfNeeded(path[0], address(_router)); _router.swapExactTokensForTokens( IERC20(swapToken).balanceOf(address(this)), desiredTokenOutMin, path, address(this), block.timestamp ); _returnAssets(path); } // OWNER FUNCTIONS function releaseStuckToken(address _token) external onlyOwner { require(_token != address(0), "cant be zero"); uint256 amount = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransfer(msg.sender, amount); } // PUBLIC VIEW FUNCTIONS function getRouter() external view returns (IMagicSeaRouter02) { return _router; } function getMasterChef() external view returns (IMasterChef) { return _masterChef; } function getWNative() external view returns (address) { return _wNative; } function getMinimumAmount() external view returns (uint256) { return _minimumAmount; } function estimateSwap(uint256 pid, address tokenIn, uint256 fullInvestmentIn) public view returns (uint256 swapAmountIn, uint256 swapAmountOut, address swapTokenOut) { checkWETH(); IMagicSeaPair pair = _getMasterChefPair(pid); bool isInputA = pair.token0() == tokenIn; require(isInputA || pair.token1() == tokenIn, "FarmZapper: Input token not present in liquidity pair"); (uint256 reserveA, uint256 reserveB,) = pair.getReserves(); (reserveA, reserveB) = isInputA ? (reserveA, reserveB) : (reserveB, reserveA); swapAmountIn = _getSwapAmount(fullInvestmentIn, reserveA, reserveB, pair.feeAmount()); swapAmountOut = _router.getAmountOut(swapAmountIn, reserveA, reserveB, pair.feeAmount()); swapTokenOut = isInputA ? pair.token1() : pair.token0(); } function checkWETH() public view returns (bool isValid) { isValid = _wNative == _router.WETH(); require(isValid, "FarmZapper: WETH address not matching Router.WETH()"); } // PRIVATE FUNCTIONS function _removeLiquidity(address pair, address to) private returns (uint256 amount0, uint256 amount1) { IERC20(pair).safeTransfer(pair, IERC20(pair).balanceOf(address(this))); (amount0, amount1) = IMagicSeaPair(pair).burn(to); require(amount0 >= _minimumAmount, "UniswapV2Router: INSUFFICIENT_A_AMOUNT"); require(amount1 >= _minimumAmount, "UniswapV2Router: INSUFFICIENT_B_AMOUNT"); } function _getMasterChefPair(uint256 pid) private view returns (IMagicSeaPair pair) { require(_masterChef.getNumberOfFarms() > pid, "no valid pid"); pair = IMagicSeaPair(address(_masterChef.getToken(pid))); require(pair.factory() == _router.factory(), "FarmZapper: Incompatible liquidity pair factory"); } function _getPair(address lpToken) private view returns (IMagicSeaPair pair) { pair = IMagicSeaPair(lpToken); require(pair.factory() == _router.factory(), "FarmZapper: Incompatible liquidity pair factory"); } function _swapAndStake(uint256 pid, uint256 tokenAmountOutMin, address tokenIn) private { IMagicSeaPair pair = _getMasterChefPair(pid); (uint256 reserveA, uint256 reserveB,) = pair.getReserves(); require(reserveA > _minimumAmount && reserveB > _minimumAmount, "FarmZapper: Liquidity pair reserves too low"); bool isInputA = pair.token0() == tokenIn; require(isInputA || pair.token1() == tokenIn, "FarmZapper: Input token not present in liquidity pair"); address[] memory path = new address[](2); path[0] = tokenIn; path[1] = isInputA ? pair.token1() : pair.token0(); uint256 fullInvestment = IERC20(tokenIn).balanceOf(address(this)); uint256 swapAmountIn; if (isInputA) { swapAmountIn = _getSwapAmount(fullInvestment, reserveA, reserveB, pair.feeAmount()); } else { swapAmountIn = _getSwapAmount(fullInvestment, reserveB, reserveA, pair.feeAmount()); } _approveTokenIfNeeded(path[0], address(_router)); uint256[] memory swapedAmounts = _router.swapExactTokensForTokens(swapAmountIn, tokenAmountOutMin, path, address(this), block.timestamp); _approveTokenIfNeeded(path[1], address(_router)); (,, uint256 amountLiquidity) = _router.addLiquidity( path[0], path[1], fullInvestment - (swapedAmounts[0]), swapedAmounts[1], 1, 1, address(this), block.timestamp ); _approveTokenIfNeeded(address(pair), address(_masterChef)); _masterChef.depositOnBehalf(pid, amountLiquidity, msg.sender); _returnAssets(path); emit SwapAndStaked(pid, tokenIn, amountLiquidity, msg.sender); } function _returnAssets(address[] memory tokens) private { uint256 balance; for (uint256 i; i < tokens.length; i++) { balance = IERC20(tokens[i]).balanceOf(address(this)); if (balance > 0) { if (tokens[i] == _wNative) { IWNATIVE(_wNative).withdraw(balance); (bool success,) = msg.sender.call{value: balance}(new bytes(0)); require(success, "FarmZapper: ETH transfer failed"); } else { IERC20(tokens[i]).safeTransfer(msg.sender, balance); } } } } function _getSwapAmount(uint256 investmentA, uint256 reserveA, uint256 reserveB, uint256 feeAmount) private view returns (uint256 swapAmount) { uint256 halfInvestment = investmentA / 2; uint256 nominator = _router.getAmountOut(halfInvestment, reserveA, reserveB, feeAmount); uint256 denominator = _router.quote(halfInvestment, reserveA + (halfInvestment), reserveB - (nominator)); swapAmount = investmentA - (FixedPointMathLib.sqrt((halfInvestment * halfInvestment * nominator) / denominator)); } function _approveTokenIfNeeded(address token, address spender) private { if (IERC20(token).allowance(address(this), spender) == 0) { IERC20(token).approve(spender, type(uint256).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../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. * * The initial owner is set to the address provided by the deployer. 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; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @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 { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _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 v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC20Permit} from "../extensions/IERC20Permit.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.8.0; /// @notice Arithmetic library with operations for fixed-point numbers. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } function powWad(int256 x, int256 y) internal pure returns (int256) { // Equivalent to x to the power of y because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y) return expWad((lnWad(x) * y) / int256(WAD)); // Using ln(x) means x must be greater than 0. } function expWad(int256 x) internal pure returns (int256 r) { unchecked { // When the result is < 0.5 we return zero. This happens when // x <= floor(log(0.5e18) * 1e18) ~ -42e18 if (x <= -42139678854452767551) return 0; // When the result is > (2**255 - 1) / 1e18 we can not represent it as an // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. if (x >= 135305999368893231589) revert("EXP_OVERFLOW"); // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 // for more intermediate precision and a binary basis. This base conversion // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. x = (x << 78) / 5**18; // Reduce range of x to (-½ ln 2, ½ ln 2) * 2**96 by factoring out powers // of two such that exp(x) = exp(x') * 2**k, where k is an integer. // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). int256 k = ((x << 96) / 54916777467707473351141471128 + 2**95) >> 96; x = x - k * 54916777467707473351141471128; // k is in the range [-61, 195]. // Evaluate using a (6, 7)-term rational approximation. // p is made monic, we'll multiply by a scale factor later. int256 y = x + 1346386616545796478920950773328; y = ((y * x) >> 96) + 57155421227552351082224309758442; int256 p = y + x - 94201549194550492254356042504812; p = ((p * y) >> 96) + 28719021644029726153956944680412240; p = p * x + (4385272521454847904659076985693276 << 96); // We leave p in 2**192 basis so we don't need to scale it back up for the division. int256 q = x - 2855989394907223263936484059900; q = ((q * x) >> 96) + 50020603652535783019961831881945; q = ((q * x) >> 96) - 533845033583426703283633433725380; q = ((q * x) >> 96) + 3604857256930695427073651918091429; q = ((q * x) >> 96) - 14423608567350463180887372962807573; q = ((q * x) >> 96) + 26449188498355588339934803723976023; assembly { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial won't have zeros in the domain as all its roots are complex. // No scaling is necessary because p is already 2**96 too large. r := sdiv(p, q) } // r should be in the range (0.09, 0.25) * 2**96. // We now need to multiply r by: // * the scale factor s = ~6.031367120. // * the 2**k factor from the range reduction. // * the 1e18 / 2**96 factor for base conversion. // We do this all at once, with an intermediate result in 2**213 // basis, so the final right shift is always by a positive amount. r = int256((uint256(r) * 3822833074963236453042738258902158003155416615667) >> uint256(195 - k)); } } function lnWad(int256 x) internal pure returns (int256 r) { unchecked { require(x > 0, "UNDEFINED"); // We want to convert x from 10**18 fixed point to 2**96 fixed point. // We do this by multiplying by 2**96 / 10**18. But since // ln(x * C) = ln(x) + ln(C), we can simply do nothing here // and add ln(2**96 / 10**18) at the end. // Reduce range of x to (1, 2) * 2**96 // ln(2^k * x) = k * ln(2) + ln(x) int256 k = int256(log2(uint256(x))) - 96; x <<= uint256(159 - k); x = int256(uint256(x) >> 159); // Evaluate using a (8, 8)-term rational approximation. // p is made monic, we will multiply by a scale factor later. int256 p = x + 3273285459638523848632254066296; p = ((p * x) >> 96) + 24828157081833163892658089445524; p = ((p * x) >> 96) + 43456485725739037958740375743393; p = ((p * x) >> 96) - 11111509109440967052023855526967; p = ((p * x) >> 96) - 45023709667254063763336534515857; p = ((p * x) >> 96) - 14706773417378608786704636184526; p = p * x - (795164235651350426258249787498 << 96); // We leave p in 2**192 basis so we don't need to scale it back up for the division. // q is monic by convention. int256 q = x + 5573035233440673466300451813936; q = ((q * x) >> 96) + 71694874799317883764090561454958; q = ((q * x) >> 96) + 283447036172924575727196451306956; q = ((q * x) >> 96) + 401686690394027663651624208769553; q = ((q * x) >> 96) + 204048457590392012362485061816622; q = ((q * x) >> 96) + 31853899698501571402653359427138; q = ((q * x) >> 96) + 909429971244387300277376558375; assembly { // Div in assembly because solidity adds a zero check despite the unchecked. // The q polynomial is known not to have zeros in the domain. // No scaling required because p is already 2**96 too large. r := sdiv(p, q) } // r is in the range (0, 0.125) * 2**96 // Finalization, we need to: // * multiply by the scale factor s = 5.549… // * add ln(2**96 / 10**18) // * add k * ln(2) // * multiply by 10**18 / 2**96 = 5**18 >> 78 // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 r *= 1677202110996718588342820967067443963516166; // add ln(2) * k * 5e18 * 2**192 r += 16597577552685614221487285958193947469193820559219878177908093499208371 * k; // add ln(2**96 / 10**18) * 5e18 * 2**192 r += 600920179829731861736702779321621459595472258049074101567377883020018308; // base conversion: mul 2**18 / 2**192 r >>= 174; } } /*////////////////////////////////////////////////////////////// LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // Divide z by the denominator. z := div(z, denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // First, divide z - 1 by the denominator and add 1. // We allow z - 1 to underflow if z is 0, because we multiply the // end result by 0 if z is zero, ensuring we return 0 if z is zero. z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1)) } } function rpow( uint256 x, uint256 n, uint256 scalar ) internal pure returns (uint256 z) { assembly { switch x case 0 { switch n case 0 { // 0 ** 0 = 1 z := scalar } default { // 0 ** n = 0 z := 0 } } default { switch mod(n, 2) case 0 { // If n is even, store scalar in z for now. z := scalar } default { // If n is odd, store x in z for now. z := x } // Shifting right by 1 is like dividing by 2. let half := shr(1, scalar) for { // Shift n right by 1 before looping to halve it. n := shr(1, n) } n { // Shift n right by 1 each iteration to halve it. n := shr(1, n) } { // Revert immediately if x ** 2 would overflow. // Equivalent to iszero(eq(div(xx, x), x)) here. if shr(128, x) { revert(0, 0) } // Store x squared. let xx := mul(x, x) // Round to the nearest number. let xxRound := add(xx, half) // Revert if xx + half overflowed. if lt(xxRound, xx) { revert(0, 0) } // Set x to scaled xxRound. x := div(xxRound, scalar) // If n is even: if mod(n, 2) { // Compute z * x. let zx := mul(z, x) // If z * x overflowed: if iszero(eq(div(zx, x), z)) { // Revert if x is non-zero. if iszero(iszero(x)) { revert(0, 0) } } // Round to the nearest number. let zxRound := add(zx, half) // Revert if zx + half overflowed. if lt(zxRound, zx) { revert(0, 0) } // Return properly scaled zxRound. z := div(zxRound, scalar) } } } } } /*////////////////////////////////////////////////////////////// GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { assembly { let y := x // We start y at x, which will help us make our initial estimate. z := 181 // The "correct" value is 1, but this saves a multiplication later. // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically. // We check y >= 2^(k + 8) but shift right by k bits // each branch to ensure that if x >= 256, then y >= 256. if iszero(lt(y, 0x10000000000000000000000000000000000)) { y := shr(128, y) z := shl(64, z) } if iszero(lt(y, 0x1000000000000000000)) { y := shr(64, y) z := shl(32, z) } if iszero(lt(y, 0x10000000000)) { y := shr(32, y) z := shl(16, z) } if iszero(lt(y, 0x1000000)) { y := shr(16, y) z := shl(8, z) } // Goal was to get z*z*y within a small factor of x. More iterations could // get y in a tighter range. Currently, we will have y in [256, 256*2^16). // We ensured y >= 256 so that the relative difference between y and y+1 is small. // That's not possible if x < 256 but we can just verify those cases exhaustively. // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. // There is no overflow risk here since y < 2^136 after the first branch above. z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181. // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) // If x+1 is a perfect square, the Babylonian method cycles between // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. // If you don't care whether the floor or ceil square root is returned, you can remove this statement. z := sub(z, lt(div(x, z), z)) } } function log2(uint256 x) internal pure returns (uint256 r) { require(x > 0, "UNDEFINED"); assembly { r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) r := or(r, shl(4, lt(0xffff, shr(r, x)))) r := or(r, shl(3, lt(0xff, shr(r, x)))) r := or(r, shl(2, lt(0xf, shr(r, x)))) r := or(r, shl(1, lt(0x3, shr(r, x)))) r := or(r, lt(0x1, shr(r, x))) } } function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) { assembly { // z will equal 0 if y is 0, unlike in Solidity where it will revert. z := mod(x, y) } } function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 z) { assembly { // z will equal 0 if y is 0, unlike in Solidity where it will revert. z := div(x, y) } } /// @dev Will return 0 instead of reverting if y is zero. function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) { assembly { // Add 1 to x * y if x % y > 0. z := add(gt(mod(x, y), 0), div(x, y)) } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0; interface IMagicSeaPair { event Approval(address indexed owner, address indexed spender, uint256 value); event Transfer(address indexed from, address indexed to, uint256 value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 value) external returns (bool); function transfer(address to, uint256 value) external returns (bool); function transferFrom(address from, address to, uint256 value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; event FeeAmountUpdated(uint256 prevFeeAmount, uint256 feeAmount); event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to); event Swap( address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint256); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint256); function price1CumulativeLast() external view returns (uint256); function kLast() external view returns (uint256); function mint(address to) external returns (uint256 liquidity); function burn(address to) external returns (uint256 amount0, uint256 amount1); function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; function feeAmount() external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.12; import "./IMagicSeaRouter01.sol"; interface IMagicSeaRouter02 is IMagicSeaRouter01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @title WNATIVE Interface * @notice Required interface of Wrapped NATIVE contract */ interface IWNATIVE is IERC20 { function deposit() external payable; function withdraw(uint256) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol"; import {IMasterChefRewarder} from "./IMasterChefRewarder.sol"; import {IMetro} from "./IMetro.sol"; import {IVoter} from "./IVoter.sol"; import {Rewarder} from "../libraries/Rewarder.sol"; import {Amounts} from "../libraries/Amounts.sol"; import {IRewarderFactory} from "./IRewarderFactory.sol"; interface IMasterChef { error MasterChef__InvalidShares(); error MasterChef__InvalidMetroPerSecond(); error MasterChef__ZeroAddress(); error MasterChef__NotMasterchefRewarder(); error MasterChef__CannotRenounceOwnership(); error MasterChef__MintFailed(); error MasterChef__TrusteeNotSet(); error MasterChef__NotTrustedCaller(); struct Farm { Amounts.Parameter amounts; Rewarder.Parameter rewarder; IERC20 token; IMasterChefRewarder extraRewarder; } // bool depositOnBehalf; // true if v2 pool zap in should be possible // uint256 startTime; event PositionModified(uint256 indexed pid, address indexed account, int256 deltaAmount, uint256 metroReward); event MetroPerSecondSet(uint256 metroPerSecond); event FarmAdded(uint256 indexed pid, IERC20 indexed token); event ExtraRewarderSet(uint256 indexed pid, IMasterChefRewarder extraRewarder); event TreasurySet(address indexed treasury); event VoterSet(IVoter indexed newVoter); event TrusteeSet(address indexed trustee); event MintMetroSet(bool mintMetro); event OperatorUpdated(address indexed operator); function add(IERC20 token, IMasterChefRewarder extraRewarder) external; function claim(uint256[] memory pids) external; function deposit(uint256 pid, uint256 amount) external; function depositOnBehalf(uint256 pid, uint256 amount, address account) external; function emergencyWithdraw(uint256 pid) external; function getDeposit(uint256 pid, address account) external view returns (uint256); function getLastUpdateTimestamp(uint256 pid) external view returns (uint256); function getPendingRewards(address account, uint256[] memory pids) external view returns (uint256[] memory metroRewards, IERC20[] memory extraTokens, uint256[] memory extraRewards); function getExtraRewarder(uint256 pid) external view returns (IMasterChefRewarder); function getMetro() external view returns (IMetro); function getMetroPerSecond() external view returns (uint256); function getMetroPerSecondForPid(uint256 pid) external view returns (uint256); function getNumberOfFarms() external view returns (uint256); function getToken(uint256 pid) external view returns (IERC20); function getTotalDeposit(uint256 pid) external view returns (uint256); function getTreasury() external view returns (address); function getTreasuryShare() external view returns (uint256); function getRewarderFactory() external view returns (IRewarderFactory); function getLBHooksManager() external view returns (address); function getVoter() external view returns (IVoter); function setExtraRewarder(uint256 pid, IMasterChefRewarder extraRewarder) external; function setMetroPerSecond(uint96 metroPerSecond) external; function setTreasury(address treasury) external; function setVoter(IVoter voter) external; function setTrustee(address trustee) external; function updateAll(uint256[] calldata pids) external; function withdraw(uint256 pid, uint256 amount) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @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. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ 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]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.6.12; interface IMagicSeaRouter01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity); function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETH( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external returns (uint256 amountToken, uint256 amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountA, uint256 amountB); function removeLiquidityETHWithPermit( address token, uint256 liquidity, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint256 amountToken, uint256 amountETH); function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactETHForTokens(uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external payable returns (uint256[] memory amounts); function swapTokensForExactETH( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapExactTokensForETH( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external returns (uint256[] memory amounts); function swapETHForExactTokens(uint256 amountOut, address[] calldata path, address to, uint256 deadline) external payable returns (uint256[] memory amounts); function quote(uint256 amountA, uint256 reserveA, uint256 reserveB) external pure returns (uint256 amountB); function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint256 feeAmount) external pure returns (uint256 amountOut); function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut, uint256 feeAmount) external pure returns (uint256 amountIn); function getAmountsOut(uint256 amountIn, address[] calldata path) external view returns (uint256[] memory amounts); function getAmountsIn(uint256 amountOut, address[] calldata path) external view returns (uint256[] memory amounts); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IBaseRewarder} from "./IBaseRewarder.sol"; interface IMasterChefRewarder is IBaseRewarder { error MasterChefRewarder__AlreadyLinked(); error MasterChefRewarder__NotLinked(); error MasterChefRewarder__UseUnlink(); enum Status { Unlinked, Linked, Stopped } function link(uint256 pid) external; function unlink(uint256 pid) external; function onEmergency(address account, uint256 pid, uint256 oldBalance, uint256 newBalance, uint256 oldTotalSupply) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol"; interface IMetro is IERC20 { function mint(address account, uint256 amount) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {IBribeRewarder} from "./IBribeRewarder.sol"; import {IMasterChef} from "./IMasterChef.sol"; interface IVoter { error IVoter__InvalidLength(); error IVoter_VotingPeriodNotStarted(); error IVoter_VotingPeriodEnded(); error IVoter__AlreadyVoted(); error IVoter__NotOwner(); error IVoter__InsufficientVotingPower(); error IVoter__TooManyPoolIds(); error IVoter__DuplicatePoolId(uint256 pid); error IVoter__InsufficientLockTime(); error Voter__InvalidRegisterCaller(); error Voter__PoolNotVotable(); error IVoter__NoFinishedPeriod(); error IVoter_ZeroValue(); error IVoter__EmergencyUnlock(); event VotingPeriodStarted(); event Voted(uint256 indexed tokenId, uint256 votingPeriod, address[] votedPools, uint256[] votesDeltaAmounts); event TopPoolIdsWithWeightsSet(uint256[] poolIds, uint256[] pidWeights); event VoterPoolValidatorUpdated(address indexed validator); event VotingDurationUpdated(uint256 duration); event MinimumLockTimeUpdated(uint256 lockTime); event MinimumVotesPerPoolUpdated(uint256 minimum); event OperatorUpdated(address indexed operator); event ElevatedRewarderAdded(address indexed rewarder); event ElevatedRewarderRemoved(address indexed rewarder); struct VotingPeriod { uint256 startTime; uint256 endTime; } function getMasterChef() external view returns (IMasterChef); function getTotalWeight() external view returns (uint256); function getTopPoolIds() external view returns (uint256[] memory); function getWeight(uint256 pid) external view returns (uint256); function hasVoted(uint256 period, uint256 tokenId) external view returns (bool); function getCurrentVotingPeriod() external view returns (uint256); function getLatestFinishedPeriod() external view returns (uint256); function getPeriodStartTime() external view returns (uint256); function getPeriodStartEndtime(uint256 periodId) external view returns (uint256, uint256); function getVotesPerPeriod(uint256 periodId, address pool) external view returns (uint256); function getVotedPools() external view returns (address[] memory); function getVotedPoolsLength() external view returns (uint256); function getVotedPoolsAtIndex(uint256 index) external view returns (address, uint256); function getTotalVotes() external view returns (uint256); function getUserVotes(uint256 tokenId, address pool) external view returns (uint256); function getPoolVotesPerPeriod(uint256 periodId, address pool) external view returns (uint256); function getUserBribeRewaderAt(uint256 period, address account, uint256 index) external view returns (IBribeRewarder); function getUserBribeRewarderLength(uint256 period, address account) external view returns (uint256); function getBribeRewarderAt(uint256 period, address pool, uint256 index) external view returns (IBribeRewarder); function getBribeRewarderLength(uint256 period, address pool) external view returns (uint256); function ownerOf(uint256 tokenId, address account) external view returns (bool); function onRegister() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Amounts} from "./Amounts.sol"; import {Constants} from "./Constants.sol"; /** * @title Rewarder Library * @dev A library that defines various functions for calculating rewards. * It takes care about the reward debt and the accumulated debt per share. */ library Rewarder { using Amounts for Amounts.Parameter; struct Parameter { uint256 lastUpdateTimestamp; uint256 accDebtPerShare; mapping(address => uint256) debt; } /** * @dev Returns the debt associated with an amount. * @param accDebtPerShare The accumulated debt per share. * @param deposit The amount. * @return The debt associated with the amount. */ function getDebt(uint256 accDebtPerShare, uint256 deposit) internal pure returns (uint256) { return (deposit * accDebtPerShare) >> Constants.ACC_PRECISION_BITS; } /** * @dev Returns the debt per share associated with a total deposit and total rewards. * @param totalDeposit The total deposit. * @param totalRewards The total rewards. * @return The debt per share associated with the total deposit and total rewards. */ function getDebtPerShare(uint256 totalDeposit, uint256 totalRewards) internal pure returns (uint256) { return totalDeposit == 0 ? 0 : (totalRewards << Constants.ACC_PRECISION_BITS) / totalDeposit; } /** * @dev Returns the total rewards to emit. * If the end timestamp is in the past, the rewards are calculated up to the end timestamp. * If the last update timestamp is in the future, it will return 0. * @param rewarder The storage pointer to the rewarder. * @param rewardPerSecond The reward per second. * @param endTimestamp The end timestamp. * @param totalSupply The total supply. * @return The total rewards. */ function getTotalRewards( Parameter storage rewarder, uint256 rewardPerSecond, uint256 endTimestamp, uint256 totalSupply ) internal view returns (uint256) { if (totalSupply == 0) return 0; uint256 lastUpdateTimestamp = rewarder.lastUpdateTimestamp; uint256 timestamp = block.timestamp > endTimestamp ? endTimestamp : block.timestamp; return timestamp > lastUpdateTimestamp ? (timestamp - lastUpdateTimestamp) * rewardPerSecond : 0; } /** * @dev Returns the total rewards to emit. * @param rewarder The storage pointer to the rewarder. * @param rewardPerSecond The reward per second. * @param totalSupply The total supply. * @return The total rewards. */ function getTotalRewards(Parameter storage rewarder, uint256 rewardPerSecond, uint256 totalSupply) internal view returns (uint256) { return getTotalRewards(rewarder, rewardPerSecond, block.timestamp, totalSupply); } /** * @dev Returns the pending reward of an account. * @param rewarder The storage pointer to the rewarder. * @param amounts The storage pointer to the amounts. * @param account The address of the account. * @param totalRewards The total rewards. * @return The pending reward of the account. */ function getPendingReward( Parameter storage rewarder, Amounts.Parameter storage amounts, address account, uint256 totalRewards ) internal view returns (uint256) { return getPendingReward(rewarder, account, amounts.getAmountOf(account), amounts.getTotalAmount(), totalRewards); } /** * @dev Returns the pending reward of an account. * If the balance of the account is 0, it will always return 0. * @param rewarder The storage pointer to the rewarder. * @param account The address of the account. * @param balance The balance of the account. * @param totalSupply The total supply. * @param totalRewards The total rewards. * @return The pending reward of the account. */ function getPendingReward( Parameter storage rewarder, address account, uint256 balance, uint256 totalSupply, uint256 totalRewards ) internal view returns (uint256) { uint256 accDebtPerShare = rewarder.accDebtPerShare + getDebtPerShare(totalSupply, totalRewards); return balance == 0 ? 0 : getDebt(accDebtPerShare, balance) - rewarder.debt[account]; } /** * @dev Updates the rewarder. * If the balance of the account is 0, it will always return 0. * @param rewarder The storage pointer to the rewarder. * @param account The address of the account. * @param oldBalance The old balance of the account. * @param newBalance The new balance of the account. * @param totalSupply The total supply. * @param totalRewards The total rewards. * @return rewards The rewards of the account. */ function update( Parameter storage rewarder, address account, uint256 oldBalance, uint256 newBalance, uint256 totalSupply, uint256 totalRewards ) internal returns (uint256 rewards) { uint256 accDebtPerShare = updateAccDebtPerShare(rewarder, totalSupply, totalRewards); rewards = oldBalance == 0 ? 0 : getDebt(accDebtPerShare, oldBalance) - rewarder.debt[account]; rewarder.debt[account] = getDebt(accDebtPerShare, newBalance); } /** * @dev Updates the accumulated debt per share. * If the last update timestamp is in the future, it will not update the last update timestamp. * @param rewarder The storage pointer to the rewarder. * @param totalSupply The total supply. * @param totalRewards The total rewards. * @return The accumulated debt per share. */ function updateAccDebtPerShare(Parameter storage rewarder, uint256 totalSupply, uint256 totalRewards) internal returns (uint256) { uint256 debtPerShare = getDebtPerShare(totalSupply, totalRewards); if (block.timestamp > rewarder.lastUpdateTimestamp) rewarder.lastUpdateTimestamp = block.timestamp; return debtPerShare == 0 ? rewarder.accDebtPerShare : rewarder.accDebtPerShare += debtPerShare; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Math} from "./Math.sol"; /** * @title Amounts Library * @dev A library that defines various functions for manipulating amounts of a key and a total. * The key can be bytes32, address, or uint256. */ library Amounts { using Math for uint256; struct Parameter { uint256 totalAmount; mapping(bytes32 => uint256) amounts; } /** * @dev Returns the amount of a key. * @param amounts The storage pointer to the amounts. * @param key The key of the amount. * @return The amount of the key. */ function getAmountOf(Parameter storage amounts, bytes32 key) internal view returns (uint256) { return amounts.amounts[key]; } /** * @dev Returns the amount of an address. * @param amounts The storage pointer to the amounts. * @param account The address of the amount. * @return The amount of the address. */ function getAmountOf(Parameter storage amounts, address account) internal view returns (uint256) { return getAmountOf(amounts, bytes32(uint256(uint160(account)))); } /** * @dev Returns the amount of an id. * @param amounts The storage pointer to the amounts. * @param id The id of the amount. * @return The amount of the id. */ function getAmountOf(Parameter storage amounts, uint256 id) internal view returns (uint256) { return getAmountOf(amounts, bytes32(id)); } /** * @dev Returns the total amount. * @param amounts The storage pointer to the amounts. * @return The total amount. */ function getTotalAmount(Parameter storage amounts) internal view returns (uint256) { return amounts.totalAmount; } /** * @dev Updates the amount of a key. The delta is added to the key amount and the total amount. * @param amounts The storage pointer to the amounts. * @param key The key of the amount. * @param deltaAmount The delta amount to update. * @return oldAmount The old amount of the key. * @return newAmount The new amount of the key. * @return oldTotalAmount The old total amount. * @return newTotalAmount The new total amount. */ function update(Parameter storage amounts, bytes32 key, int256 deltaAmount) internal returns (uint256 oldAmount, uint256 newAmount, uint256 oldTotalAmount, uint256 newTotalAmount) { oldAmount = amounts.amounts[key]; oldTotalAmount = amounts.totalAmount; if (deltaAmount == 0) { newAmount = oldAmount; newTotalAmount = oldTotalAmount; } else { newAmount = oldAmount.addDelta(deltaAmount); newTotalAmount = oldTotalAmount.addDelta(deltaAmount); amounts.amounts[key] = newAmount; amounts.totalAmount = newTotalAmount; } } /** * @dev Updates the amount of an address. The delta is added to the address amount and the total amount. * @param amounts The storage pointer to the amounts. * @param account The address of the amount. * @param deltaAmount The delta amount to update. * @return oldAmount The old amount of the key. * @return newAmount The new amount of the key. * @return oldTotalAmount The old total amount. * @return newTotalAmount The new total amount. */ function update(Parameter storage amounts, address account, int256 deltaAmount) internal returns (uint256 oldAmount, uint256 newAmount, uint256 oldTotalAmount, uint256 newTotalAmount) { return update(amounts, bytes32(uint256(uint160(account))), deltaAmount); } /** * @dev Updates the amount of an id. The delta is added to the id amount and the total amount. * @param amounts The storage pointer to the amounts. * @param id The id of the amount. * @param deltaAmount The delta amount to update. * @return oldAmount The old amount of the key. * @return newAmount The new amount of the key. * @return oldTotalAmount The old total amount. * @return newTotalAmount The new total amount. */ function update(Parameter storage amounts, uint256 id, int256 deltaAmount) internal returns (uint256 oldAmount, uint256 newAmount, uint256 oldTotalAmount, uint256 newTotalAmount) { return update(amounts, bytes32(id), deltaAmount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol"; import {IRewarder} from "../interfaces/IRewarder.sol"; import {IBribeRewarder} from "../interfaces/IBribeRewarder.sol"; import {IBaseRewarder} from "../interfaces/IBaseRewarder.sol"; interface IRewarderFactory { error RewarderFactory__ZeroAddress(); error RewarderFactory__InvalidRewarderType(); error RewarderFactory__InvalidPid(); error RewarderFactory__TokenNotWhitelisted(); error RewarderFactory__InvalidLength(); enum RewarderType { InvalidRewarder, MasterChefRewarder, BribeRewarder } event RewarderCreated( RewarderType indexed rewarderType, IERC20 indexed token, uint256 indexed pid, IBaseRewarder rewarder ); event BribeRewarderCreated( RewarderType indexed rewarderType, IERC20 indexed token, address indexed pool, IBribeRewarder rewarder ); event RewarderImplementationSet(RewarderType indexed rewarderType, IRewarder indexed implementation); function getBribeCreatorFee() external view returns (uint256); function getWhitelistedTokenInfo (address token) external view returns (bool, uint256); function getRewarderImplementation(RewarderType rewarderType) external view returns (IRewarder); function getRewarderCount(RewarderType rewarderType) external view returns (uint256); function getRewarderAt(RewarderType rewarderType, uint256 index) external view returns (IRewarder); function getRewarderType(IRewarder rewarder) external view returns (RewarderType); function setRewarderImplementation(RewarderType rewarderType, IRewarder implementation) external; function createRewarder(RewarderType rewarderType, IERC20 token, uint256 pid) external returns (IBaseRewarder); function createBribeRewarder(IERC20 token, address pool) external returns (IBribeRewarder); function setWhitelist(address[] calldata tokens, uint256[] calldata minBribeAmounts) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol"; import {IRewarder} from "./IRewarder.sol"; interface IBaseRewarder is IRewarder { error BaseRewarder__NativeTransferFailed(); error BaseRewarder__InvalidCaller(); error BaseRewarder__Stopped(); error BaseRewarder__AlreadyStopped(); error BaseRewarder__NotNativeRewarder(); error BaseRewarder__ZeroAmount(); error BaseRewarder__ZeroReward(); error BaseRewarder__InvalidDuration(); error BaseRewarder__InvalidPid(uint256 pid); error BaseRewarder__InvalidStartTimestamp(uint256 startTimestamp); error BaseRewarder__CannotRenounceOwnership(); event Claim(address indexed account, IERC20 indexed token, uint256 reward); event RewardParameterUpdated(uint256 rewardPerSecond, uint256 startTimestamp, uint256 endTimestamp); event Stopped(); event Swept(IERC20 indexed token, address indexed account, uint256 amount); function getToken() external view returns (IERC20); function getCaller() external view returns (address); function getPid() external view returns (uint256); function getRewarderParameter() external view returns (IERC20 token, uint256 rewardPerSecond, uint256 lastUpdateTimestamp, uint256 endTimestamp); function getRemainingReward() external view returns (uint256); function getPendingReward(address account, uint256 balance, uint256 totalSupply) external view returns (IERC20 token, uint256 pendingReward); function isStopped() external view returns (bool); function initialize(address initialOwner) external; function setRewardPerSecond(uint256 maxRewardPerSecond, uint256 expectedDuration) external returns (uint256 rewardPerSecond); function setRewarderParameters(uint256 maxRewardPerSecond, uint256 startTimestamp, uint256 expectedDuration) external returns (uint256 rewardPerSecond); function stop() external; function sweep(IERC20 token, address account) external; function onModify(address account, uint256 pid, uint256 oldBalance, uint256 newBalance, uint256 totalSupply) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol"; import {IRewarder} from "./IRewarder.sol"; interface IBribeRewarder is IRewarder { error BribeRewarder__OnlyVoter(); error BribeRewarder__InsufficientFunds(); error BribeRewarder__WrongStartId(); error BribeRewarder__WrongEndId(); error BribeRewarder__ZeroReward(); error BribeRewarder__NativeTransferFailed(); error BribeRewarder__NotOwner(); error BribeRewarder__CannotRenounceOwnership(); error BribeRewarder__NotNativeRewarder(); error BribeRewarder__AlreadyInitialized(); error BribeRewarder__PeriodNotFound(); error BribeRewarder__AmountTooLow(); error BribeRewarder__OnlyVoterAdmin(); event Claimed(address indexed account, address indexed pool, uint256 amount); event Deposited(uint256 indexed periodId, address indexed account, address indexed pool, uint256 amount); event BribeInit(uint256 indexed startId, uint256 indexed lastId, uint256 amountPerPeriod); event Swept(IERC20 indexed token, address indexed account, uint256 amount); function bribe(uint256 startId, uint256 lastId, uint256 amountPerPeriod) external; function claim(address account) external; function deposit(uint256 periodId, address account, uint256 deltaAmount) external; function getPool() external view returns (address); function getPendingReward(address account) external view returns (uint256); function getBribePeriods() external view returns (address pool, uint256[] memory); function getStartVotingPeriodId() external view returns (uint256); function getLastVotingPeriodId() external view returns (uint256); function getAmountPerPeriod() external view returns (uint256); function sweep(IERC20 token, address account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title Constants Library * @dev A library that defines various constants used throughout the codebase. */ library Constants { uint256 internal constant ACC_PRECISION_BITS = 64; uint256 internal constant PRECISION = 1e18; uint256 internal constant MAX_NUMBER_OF_FARMS = 32; uint256 internal constant MAX_NUMBER_OF_REWARDS = 32; uint256 internal constant MAX_METRO_PER_SECOND = 10e18; uint256 internal constant MAX_BRIBES_PER_POOL = 5; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title Math * @dev Library for mathematical operations with overflow and underflow checks. */ library Math { error Math__UnderOverflow(); uint256 internal constant MAX_INT256 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; /** * @dev Adds a signed integer to an unsigned integer with overflow check. * The result must be greater than or equal to 0 and less than or equal to MAX_INT256. * @param x Unsigned integer to add to. * @param delta Signed integer to add. * @return y The result of the addition. */ function addDelta(uint256 x, int256 delta) internal pure returns (uint256 y) { uint256 success; assembly { y := add(x, delta) success := iszero(or(gt(x, MAX_INT256), gt(y, MAX_INT256))) } if (success == 0) revert Math__UnderOverflow(); } /** * @dev Safely converts an unsigned integer to a signed integer. * @param x Unsigned integer to convert. * @return y Signed integer result. */ function toInt256(uint256 x) internal pure returns (int256 y) { if (x > MAX_INT256) revert Math__UnderOverflow(); return int256(x); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20} from "openzeppelin/token/ERC20/IERC20.sol"; interface IRewarder { function getToken() external view returns (IERC20); function getCaller() external view returns (address); function initialize(address initialOwner) external; }
{ "remappings": [ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin/=lib/openzeppelin-contracts/contracts/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "solmate/=lib/solmate/", "joe-v2/=lib/joe-v2/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 800 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"router","type":"address"},{"internalType":"address","name":"masterchef","type":"address"},{"internalType":"address","name":"wNative","type":"address"},{"internalType":"uint256","name":"minimumAmount","type":"uint256"},{"internalType":"address","name":"admin","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":true,"internalType":"address","name":"tokenIn","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountLiquidity","type":"uint256"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"SwapAndStaked","type":"event"},{"inputs":[],"name":"checkWETH","outputs":[{"internalType":"bool","name":"isValid","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"fullInvestmentIn","type":"uint256"}],"name":"estimateSwap","outputs":[{"internalType":"uint256","name":"swapAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapAmountOut","type":"uint256"},{"internalType":"address","name":"swapTokenOut","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMasterChef","outputs":[{"internalType":"contract IMasterChef","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinimumAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRouter","outputs":[{"internalType":"contract IMagicSeaRouter02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWNative","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"releaseStuckToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"tokenAmountOutMin","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"tokenInAmount","type":"uint256"}],"name":"zapIn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"tokenAmountOutMin","type":"uint256"}],"name":"zapInWNative","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutAMin","type":"uint256"},{"internalType":"uint256","name":"amountOutBMin","type":"uint256"}],"name":"zapOut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lpToken","type":"address"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"},{"internalType":"address","name":"desiredToken","type":"address"},{"internalType":"uint256","name":"desiredTokenOutMin","type":"uint256"}],"name":"zapOutAndSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620032dd380380620032dd8339810160408190526200003591620001f0565b806001600160a01b0381166200006657604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b620000718162000183565b50826001600160a01b0316856001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000bb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000e1919062000257565b6001600160a01b0316146200015f5760405162461bcd60e51b815260206004820152603660248201527f4661726d5a61707065723a20774e61746976652061646472657373206e6f742060448201527f6d61746368696e6720526f757465722e5745544828290000000000000000000060648201526084016200005d565b506001600160a01b0393841660805291831660a05290911660c05260e0526200027c565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620001eb57600080fd5b919050565b600080600080600060a086880312156200020957600080fd5b6200021486620001d3565b94506200022460208701620001d3565b93506200023460408701620001d3565b9250606086015191506200024b60808701620001d3565b90509295509295909350565b6000602082840312156200026a57600080fd5b6200027582620001d3565b9392505050565b60805160a05160c05160e051612f64620003796000396000818161018001528181610926015281816113b501528181611aed01528181611b17015281816123d9015261245801526000818160f1015281816101cd0152818161088301528181610ab901528181610b5701528181611434015281816114ad0152818161257901526125df0152600081816102ca015281816114d6015281816115b90152818161217901526121c0015260008181610277015281816105fd015281816107f80152818161127d015281816112be01528181611630015281816117e30152818161185c01528181611f900152818161203001526122870152612f646000f3fe6080604052600436106100e15760003560e01c8063b0f479a11161007f578063b5c74d5211610059578063b5c74d52146102ee578063f2fde38b1461030e578063f3cc669a1461032e578063fce8e0ce1461034e57600080fd5b8063b0f479a114610268578063b30bebe71461029b578063b5644963146102bb57600080fd5b8063719a08a3116100bb578063719a08a3146101be5780638437fabe146102055780638da5cb5b1461022a5780639fd32c1d1461024857600080fd5b80634f880c4b1461012557806362066eb31461016e578063715018a6146101a957600080fd5b3661012057336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461011e5761011e612ab6565b005b600080fd5b34801561013157600080fd5b50610145610140366004612ae1565b610361565b6040805193845260208401929092526001600160a01b0316908201526060015b60405180910390f35b34801561017a57600080fd5b506040517f00000000000000000000000000000000000000000000000000000000000000008152602001610165565b3480156101b557600080fd5b5061011e6107e0565b3480156101ca57600080fd5b507f00000000000000000000000000000000000000000000000000000000000000005b6040516001600160a01b039091168152602001610165565b34801561021157600080fd5b5061021a6107f4565b6040519015158152602001610165565b34801561023657600080fd5b506000546001600160a01b03166101ed565b34801561025457600080fd5b5061011e610263366004612b19565b610924565b34801561027457600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101ed565b3480156102a757600080fd5b5061011e6102b6366004612b58565b610a92565b3480156102c757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006101ed565b3480156102fa57600080fd5b5061011e610309366004612b93565b610eee565b34801561031a57600080fd5b5061011e610329366004612b93565b610fd1565b34801561033a57600080fd5b5061011e610349366004612bb0565b61100f565b61011e61035c366004612be8565b6113b3565b600080600061036e6107f4565b50600061037a876114d1565b90506000866001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ea9190612c0a565b6001600160a01b031614905080806104745750866001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610445573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104699190612c0a565b6001600160a01b0316145b6104eb5760405162461bcd60e51b815260206004820152603560248201527f4661726d5a61707065723a20496e70757420746f6b656e206e6f74207072657360448201527f656e7420696e206c69717569646974792070616972000000000000000000000060648201526084015b60405180910390fd5b600080836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561052c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105509190612c45565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915082610581578082610584565b81815b80925081935050506105f9888383876001600160a01b03166369e154046040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f49190612c95565b61179c565b96507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166352707d8c888484886001600160a01b03166369e154046040518163ffffffff1660e01b8152600401602060405180830381865afa15801561066b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068f9190612c95565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401602060405180830381865afa1580156106dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107019190612c95565b95508261076f57836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076a9190612c0a565b6107d1565b836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d19190612c0a565b94505050505093509350939050565b6107e8611943565b6107f26000611970565b565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610854573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108789190612c0a565b6001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316149050806109215760405162461bcd60e51b815260206004820152603360248201527f4661726d5a61707065723a20574554482061646472657373206e6f74206d617460448201527f6368696e6720526f757465722e5745544828290000000000000000000000000060648201526084016104e2565b90565b7f00000000000000000000000000000000000000000000000000000000000000008110156109a35760405162461bcd60e51b815260206004820152602660248201527f4661726d5a61707065723a20496e7369676e69666963616e7420696e70757420604482015265185b5bdd5b9d60d21b60648201526084016104e2565b604051636eb1769f60e11b815233600482015230602482015281906001600160a01b0384169063dd62ed3e90604401602060405180830381865afa1580156109ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a139190612c95565b1015610a6c5760405162461bcd60e51b815260206004820152602260248201527f42656566793a20496e70757420746f6b656e206973206e6f7420617070726f76604482015261195960f21b60648201526084016104e2565b610a816001600160a01b0383163330846119d8565b610a8c848484611a54565b50505050565b6000610a9d85612280565b9050610ab46001600160a01b0386163330876119d8565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b439190612c0a565b6001600160a01b031614158015610bed57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be19190612c0a565b6001600160a01b031614155b15610cc557610bfc83336122e3565b909250905084821015610c5f5760405162461bcd60e51b815260206004820152602560248201527f4d61676963536561526f757465723a20494e53554646494349454e545f415f416044820152641353d5539560da1b60648201526084016104e2565b83811015610cbd5760405162461bcd60e51b815260206004820152602560248201527f4d61676963536561526f757465723a20494e53554646494349454e545f425f416044820152641353d5539560da1b60648201526084016104e2565b505050610a8c565b610ccf83306122e3565b909250905084821015610d325760405162461bcd60e51b815260206004820152602560248201527f4d61676963536561526f757465723a20494e53554646494349454e545f415f416044820152641353d5539560da1b60648201526084016104e2565b83811015610d905760405162461bcd60e51b815260206004820152602560248201527f4d61676963536561526f757465723a20494e53554646494349454e545f425f416044820152641353d5539560da1b60648201526084016104e2565b604080516002808252606082018352600092602083019080368337019050509050836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610def573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e139190612c0a565b81600081518110610e2657610e26612cc4565b60200260200101906001600160a01b031690816001600160a01b031681525050836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea89190612c0a565b81600181518110610ebb57610ebb612cc4565b60200260200101906001600160a01b031690816001600160a01b031681525050610ee4816124dc565b5050505050505050565b610ef6611943565b6001600160a01b038116610f4c5760405162461bcd60e51b815260206004820152600c60248201527f63616e74206265207a65726f000000000000000000000000000000000000000060448201526064016104e2565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb79190612c95565b9050610fcd6001600160a01b038316338361274a565b5050565b610fd9611943565b6001600160a01b03811661100357604051631e4fbdf760e01b8152600060048201526024016104e2565b61100c81611970565b50565b600061101a85612280565b90506000816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110809190612c0a565b90506000826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e69190612c0a565b9050846001600160a01b0316826001600160a01b031614806111195750846001600160a01b0316816001600160a01b0316145b61118b5760405162461bcd60e51b815260206004820152603760248201527f4661726d5a61707065723a206465736972656420746f6b656e206e6f7420707260448201527f6573656e7420696e206c6971756964697479207061697200000000000000000060648201526084016104e2565b6111a06001600160a01b0388163330896119d8565b6111aa83306122e3565b50506000856001600160a01b0316826001600160a01b0316146111cd57816111cf565b825b6040805160028082526060820183529293506000929091602083019080368337019050509050818160008151811061120957611209612cc4565b60200260200101906001600160a01b031690816001600160a01b031681525050868160018151811061123d5761123d612cc4565b60200260200101906001600160a01b031690816001600160a01b0316815250506112a18160008151811061127357611273612cc4565b60200260200101517f000000000000000000000000000000000000000000000000000000000000000061277b565b6040516370a0823160e01b81523060048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116916338ed1739918516906370a0823190602401602060405180830381865afa15801561130f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113339190612c95565b888430426040518663ffffffff1660e01b8152600401611357959493929190612cda565b6000604051808303816000875af1158015611376573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261139e9190810190612d4b565b506113a8816124dc565b505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000003410156114325760405162461bcd60e51b815260206004820152602660248201527f4661726d5a61707065723a20496e7369676e69666963616e7420696e70757420604482015265185b5bdd5b9d60d21b60648201526084016104e2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561148d57600080fd5b505af11580156114a1573d6000803e3d6000fd5b5050505050610fcd82827f0000000000000000000000000000000000000000000000000000000000000000611a54565b6000817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c7a617836040518163ffffffff1660e01b8152600401602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115569190612c95565b116115a35760405162461bcd60e51b815260206004820152600c60248201527f6e6f2076616c696420706964000000000000000000000000000000000000000060448201526064016104e2565b604051631c96a19760e31b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e4b50cb890602401602060405180830381865afa158015611608573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162c9190612c0a565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561168c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b09190612c0a565b6001600160a01b0316816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171b9190612c0a565b6001600160a01b0316146117975760405162461bcd60e51b815260206004820152602f60248201527f4661726d5a61707065723a20496e636f6d70617469626c65206c69717569646960448201527f7479207061697220666163746f7279000000000000000000000000000000000060648201526084016104e2565b919050565b6000806117aa600287612e13565b60405163149c1f6360e21b8152600481018290526024810187905260448101869052606481018590529091506000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906352707d8c90608401602060405180830381865afa15801561182a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184e9190612c95565b905060006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663ad615dec8461188c818b612e35565b611896868b612e48565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa1580156118df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119039190612c95565b905061192d81836119148680612e5b565b61191e9190612e5b565b6119289190612e13565b612866565b6119379089612e48565b98975050505050505050565b6000546001600160a01b031633146107f25760405163118cdaa760e01b81523360048201526024016104e2565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038481166024830152838116604483015260648201839052610a8c9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612918565b6000611a5f846114d1565b9050600080826001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac69190612c45565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691507f000000000000000000000000000000000000000000000000000000000000000082118015611b3957507f000000000000000000000000000000000000000000000000000000000000000081115b611bab5760405162461bcd60e51b815260206004820152602b60248201527f4661726d5a61707065723a204c6971756964697479207061697220726573657260448201527f76657320746f6f206c6f7700000000000000000000000000000000000000000060648201526084016104e2565b6000846001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c199190612c0a565b6001600160a01b03161490508080611ca35750846001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c989190612c0a565b6001600160a01b0316145b611d155760405162461bcd60e51b815260206004820152603560248201527f4661726d5a61707065723a20496e70757420746f6b656e206e6f74207072657360448201527f656e7420696e206c69717569646974792070616972000000000000000000000060648201526084016104e2565b6040805160028082526060820183526000926020830190803683370190505090508581600081518110611d4a57611d4a612cc4565b60200260200101906001600160a01b031690816001600160a01b03168152505081611dd657846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd19190612c0a565b611e38565b846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e389190612c0a565b81600181518110611e4b57611e4b612cc4565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b81523060048201526000918816906370a0823190602401602060405180830381865afa158015611ea0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec49190612c95565b905060008315611f1957611f128287878a6001600160a01b03166369e154046040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d6000803e3d6000fd5b9050611f60565b611f5d8286888a6001600160a01b03166369e154046040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d6000803e3d6000fd5b90505b611f768360008151811061127357611273612cc4565b6040516338ed173960e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906338ed173990611fcd9085908e90899030904290600401612cda565b6000604051808303816000875af1158015611fec573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120149190810190612d4b565b905061202c8460018151811061127357611273612cc4565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e8e337008660008151811061207057612070612cc4565b60200260200101518760018151811061208b5761208b612cc4565b6020026020010151856000815181106120a6576120a6612cc4565b6020026020010151886120b99190612e48565b866001815181106120cc576120cc612cc4565b60209081029190910101516040516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526044830152606482015260016084820181905260a48201523060c48201524260e4820152610104016060604051808303816000875af115801561214b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216f9190612e72565b9250505061219d897f000000000000000000000000000000000000000000000000000000000000000061277b565b6040516363bee36960e01b8152600481018d9052602481018290523360448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906363bee36990606401600060405180830381600087803b15801561220c57600080fd5b505af1158015612220573d6000803e3d6000fd5b5050505061222d856124dc565b604080518281523360208201526001600160a01b038c16918e917f9b5607cdd9256c448f093ce5dada1c5fae6043185c03da7ca94051577678d72a910160405180910390a3505050505050505050505050565b60008190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561168c573d6000803e3d6000fd5b6040516370a0823160e01b815230600482015260009081906123679085906001600160a01b038216906370a0823190602401602060405180830381865afa158015612332573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123569190612c95565b6001600160a01b038716919061274a565b60405163226bf2d160e21b81526001600160a01b0384811660048301528516906389afcb449060240160408051808303816000875af11580156123ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d29190612ea0565b90925090507f00000000000000000000000000000000000000000000000000000000000000008210156124565760405162461bcd60e51b815260206004820152602660248201527f556e69737761705632526f757465723a20494e53554646494349454e545f415f604482015265105353d5539560d21b60648201526084016104e2565b7f00000000000000000000000000000000000000000000000000000000000000008110156124d55760405162461bcd60e51b815260206004820152602660248201527f556e69737761705632526f757465723a20494e53554646494349454e545f425f604482015265105353d5539560d21b60648201526084016104e2565b9250929050565b6000805b8251811015612745578281815181106124fb576124fb612cc4565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561254b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256f9190612c95565b91508115612733577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168382815181106125b3576125b3612cc4565b60200260200101516001600160a01b0316036126fc57604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561262b57600080fd5b505af115801561263f573d6000803e3d6000fd5b50506040805160008082526020820192839052935033925085916126639190612ec4565b60006040518083038185875af1925050503d80600081146126a0576040519150601f19603f3d011682016040523d82523d6000602084013e6126a5565b606091505b50509050806126f65760405162461bcd60e51b815260206004820152601f60248201527f4661726d5a61707065723a20455448207472616e73666572206661696c65640060448201526064016104e2565b50612733565b612733338385848151811061271357612713612cc4565b60200260200101516001600160a01b031661274a9092919063ffffffff16565b8061273d81612ef3565b9150506124e0565b505050565b6040516001600160a01b0383811660248301526044820183905261274591859182169063a9059cbb90606401611a0d565b604051636eb1769f60e11b81523060048201526001600160a01b03828116602483015283169063dd62ed3e90604401602060405180830381865afa1580156127c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127eb9190612c95565b600003610fcd5760405163095ea7b360e01b81526001600160a01b038281166004830152600019602483015283169063095ea7b3906044016020604051808303816000875af1158015612842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127459190612f0c565b60b58171010000000000000000000000000000000000811061288d5760409190911b9060801c5b690100000000000000000081106128a95760209190911b9060401c5b6501000000000081106128c15760109190911b9060201c5b630100000081106128d75760089190911b9060101c5b62010000010260121c80820401600190811c80830401811c80830401811c80830401811c80830401811c80830401811c80830401901c908190048111900390565b600061292d6001600160a01b0384168361297b565b905080516000141580156129525750808060200190518101906129509190612f0c565b155b1561274557604051635274afe760e01b81526001600160a01b03841660048201526024016104e2565b606061298983836000612992565b90505b92915050565b6060814710156129b75760405163cd78605960e01b81523060048201526024016104e2565b600080856001600160a01b031684866040516129d39190612ec4565b60006040518083038185875af1925050503d8060008114612a10576040519150601f19603f3d011682016040523d82523d6000602084013e612a15565b606091505b5091509150612a25868383612a31565b925050505b9392505050565b606082612a4657612a4182612a8d565b612a2a565b8151158015612a5d57506001600160a01b0384163b155b15612a8657604051639996b31560e01b81526001600160a01b03851660048201526024016104e2565b5080612a2a565b805115612a9d5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b634e487b7160e01b600052600160045260246000fd5b6001600160a01b038116811461100c57600080fd5b600080600060608486031215612af657600080fd5b833592506020840135612b0881612acc565b929592945050506040919091013590565b60008060008060808587031215612b2f57600080fd5b84359350602085013592506040850135612b4881612acc565b9396929550929360600135925050565b60008060008060808587031215612b6e57600080fd5b8435612b7981612acc565b966020860135965060408601359560600135945092505050565b600060208284031215612ba557600080fd5b8135612a2a81612acc565b60008060008060808587031215612bc657600080fd5b8435612bd181612acc565b9350602085013592506040850135612b4881612acc565b60008060408385031215612bfb57600080fd5b50508035926020909101359150565b600060208284031215612c1c57600080fd5b8151612a2a81612acc565b80516dffffffffffffffffffffffffffff8116811461179757600080fd5b600080600060608486031215612c5a57600080fd5b612c6384612c27565b9250612c7160208501612c27565b9150604084015163ffffffff81168114612c8a57600080fd5b809150509250925092565b600060208284031215612ca757600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015612d2a5784516001600160a01b031683529383019391830191600101612d05565b50506001600160a01b03969096166060850152505050608001529392505050565b60006020808385031215612d5e57600080fd5b825167ffffffffffffffff80821115612d7657600080fd5b818501915085601f830112612d8a57600080fd5b815181811115612d9c57612d9c612cae565b8060051b604051601f19603f83011681018181108582111715612dc157612dc1612cae565b604052918252848201925083810185019188831115612ddf57600080fd5b938501935b8285101561193757845184529385019392850192612de4565b634e487b7160e01b600052601160045260246000fd5b600082612e3057634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561298c5761298c612dfd565b8181038181111561298c5761298c612dfd565b808202811582820484141761298c5761298c612dfd565b600080600060608486031215612e8757600080fd5b8351925060208401519150604084015190509250925092565b60008060408385031215612eb357600080fd5b505080516020909101519092909150565b6000825160005b81811015612ee55760208186018101518583015201612ecb565b506000920191825250919050565b600060018201612f0557612f05612dfd565b5060010190565b600060208284031215612f1e57600080fd5b81518015158114612a2a57600080fdfea2646970667358221220feb5205d6f7d552df8c4bb26c1e14c02212754c8423581a9302836e54c1184f764736f6c6343000814003300000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a67500000000000000000000000072a42e8a344eb66aca9ed13d5c633731cf54eeea000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000000000000000000000000000000000000000003e80000000000000000000000004a3723b6e427ecbd90f2848d6df9381a676a02b9
Deployed Bytecode
0x6080604052600436106100e15760003560e01c8063b0f479a11161007f578063b5c74d5211610059578063b5c74d52146102ee578063f2fde38b1461030e578063f3cc669a1461032e578063fce8e0ce1461034e57600080fd5b8063b0f479a114610268578063b30bebe71461029b578063b5644963146102bb57600080fd5b8063719a08a3116100bb578063719a08a3146101be5780638437fabe146102055780638da5cb5b1461022a5780639fd32c1d1461024857600080fd5b80634f880c4b1461012557806362066eb31461016e578063715018a6146101a957600080fd5b3661012057336001600160a01b037f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38161461011e5761011e612ab6565b005b600080fd5b34801561013157600080fd5b50610145610140366004612ae1565b610361565b6040805193845260208401929092526001600160a01b0316908201526060015b60405180910390f35b34801561017a57600080fd5b506040517f00000000000000000000000000000000000000000000000000000000000003e88152602001610165565b3480156101b557600080fd5b5061011e6107e0565b3480156101ca57600080fd5b507f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad385b6040516001600160a01b039091168152602001610165565b34801561021157600080fd5b5061021a6107f4565b6040519015158152602001610165565b34801561023657600080fd5b506000546001600160a01b03166101ed565b34801561025457600080fd5b5061011e610263366004612b19565b610924565b34801561027457600080fd5b507f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a6756101ed565b3480156102a757600080fd5b5061011e6102b6366004612b58565b610a92565b3480156102c757600080fd5b507f00000000000000000000000072a42e8a344eb66aca9ed13d5c633731cf54eeea6101ed565b3480156102fa57600080fd5b5061011e610309366004612b93565b610eee565b34801561031a57600080fd5b5061011e610329366004612b93565b610fd1565b34801561033a57600080fd5b5061011e610349366004612bb0565b61100f565b61011e61035c366004612be8565b6113b3565b600080600061036e6107f4565b50600061037a876114d1565b90506000866001600160a01b0316826001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103ea9190612c0a565b6001600160a01b031614905080806104745750866001600160a01b0316826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610445573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104699190612c0a565b6001600160a01b0316145b6104eb5760405162461bcd60e51b815260206004820152603560248201527f4661726d5a61707065723a20496e70757420746f6b656e206e6f74207072657360448201527f656e7420696e206c69717569646974792070616972000000000000000000000060648201526084015b60405180910390fd5b600080836001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561052c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105509190612c45565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915082610581578082610584565b81815b80925081935050506105f9888383876001600160a01b03166369e154046040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f49190612c95565b61179c565b96507f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a6756001600160a01b03166352707d8c888484886001600160a01b03166369e154046040518163ffffffff1660e01b8152600401602060405180830381865afa15801561066b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068f9190612c95565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401602060405180830381865afa1580156106dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107019190612c95565b95508261076f57836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610746573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076a9190612c0a565b6107d1565b836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d19190612c0a565b94505050505093509350939050565b6107e8611943565b6107f26000611970565b565b60007f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a6756001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610854573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108789190612c0a565b6001600160a01b03167f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad386001600160a01b0316149050806109215760405162461bcd60e51b815260206004820152603360248201527f4661726d5a61707065723a20574554482061646472657373206e6f74206d617460448201527f6368696e6720526f757465722e5745544828290000000000000000000000000060648201526084016104e2565b90565b7f00000000000000000000000000000000000000000000000000000000000003e88110156109a35760405162461bcd60e51b815260206004820152602660248201527f4661726d5a61707065723a20496e7369676e69666963616e7420696e70757420604482015265185b5bdd5b9d60d21b60648201526084016104e2565b604051636eb1769f60e11b815233600482015230602482015281906001600160a01b0384169063dd62ed3e90604401602060405180830381865afa1580156109ef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a139190612c95565b1015610a6c5760405162461bcd60e51b815260206004820152602260248201527f42656566793a20496e70757420746f6b656e206973206e6f7420617070726f76604482015261195960f21b60648201526084016104e2565b610a816001600160a01b0383163330846119d8565b610a8c848484611a54565b50505050565b6000610a9d85612280565b9050610ab46001600160a01b0386163330876119d8565b6000807f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad386001600160a01b0316836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b439190612c0a565b6001600160a01b031614158015610bed57507f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad386001600160a01b0316836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bbd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be19190612c0a565b6001600160a01b031614155b15610cc557610bfc83336122e3565b909250905084821015610c5f5760405162461bcd60e51b815260206004820152602560248201527f4d61676963536561526f757465723a20494e53554646494349454e545f415f416044820152641353d5539560da1b60648201526084016104e2565b83811015610cbd5760405162461bcd60e51b815260206004820152602560248201527f4d61676963536561526f757465723a20494e53554646494349454e545f425f416044820152641353d5539560da1b60648201526084016104e2565b505050610a8c565b610ccf83306122e3565b909250905084821015610d325760405162461bcd60e51b815260206004820152602560248201527f4d61676963536561526f757465723a20494e53554646494349454e545f415f416044820152641353d5539560da1b60648201526084016104e2565b83811015610d905760405162461bcd60e51b815260206004820152602560248201527f4d61676963536561526f757465723a20494e53554646494349454e545f425f416044820152641353d5539560da1b60648201526084016104e2565b604080516002808252606082018352600092602083019080368337019050509050836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610def573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e139190612c0a565b81600081518110610e2657610e26612cc4565b60200260200101906001600160a01b031690816001600160a01b031681525050836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea89190612c0a565b81600181518110610ebb57610ebb612cc4565b60200260200101906001600160a01b031690816001600160a01b031681525050610ee4816124dc565b5050505050505050565b610ef6611943565b6001600160a01b038116610f4c5760405162461bcd60e51b815260206004820152600c60248201527f63616e74206265207a65726f000000000000000000000000000000000000000060448201526064016104e2565b6040516370a0823160e01b81523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb79190612c95565b9050610fcd6001600160a01b038316338361274a565b5050565b610fd9611943565b6001600160a01b03811661100357604051631e4fbdf760e01b8152600060048201526024016104e2565b61100c81611970565b50565b600061101a85612280565b90506000816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110809190612c0a565b90506000826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110e69190612c0a565b9050846001600160a01b0316826001600160a01b031614806111195750846001600160a01b0316816001600160a01b0316145b61118b5760405162461bcd60e51b815260206004820152603760248201527f4661726d5a61707065723a206465736972656420746f6b656e206e6f7420707260448201527f6573656e7420696e206c6971756964697479207061697200000000000000000060648201526084016104e2565b6111a06001600160a01b0388163330896119d8565b6111aa83306122e3565b50506000856001600160a01b0316826001600160a01b0316146111cd57816111cf565b825b6040805160028082526060820183529293506000929091602083019080368337019050509050818160008151811061120957611209612cc4565b60200260200101906001600160a01b031690816001600160a01b031681525050868160018151811061123d5761123d612cc4565b60200260200101906001600160a01b031690816001600160a01b0316815250506112a18160008151811061127357611273612cc4565b60200260200101517f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a67561277b565b6040516370a0823160e01b81523060048201526001600160a01b037f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a6758116916338ed1739918516906370a0823190602401602060405180830381865afa15801561130f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113339190612c95565b888430426040518663ffffffff1660e01b8152600401611357959493929190612cda565b6000604051808303816000875af1158015611376573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261139e9190810190612d4b565b506113a8816124dc565b505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000003e83410156114325760405162461bcd60e51b815260206004820152602660248201527f4661726d5a61707065723a20496e7369676e69666963616e7420696e70757420604482015265185b5bdd5b9d60d21b60648201526084016104e2565b7f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad386001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561148d57600080fd5b505af11580156114a1573d6000803e3d6000fd5b5050505050610fcd82827f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38611a54565b6000817f00000000000000000000000072a42e8a344eb66aca9ed13d5c633731cf54eeea6001600160a01b031663c7a617836040518163ffffffff1660e01b8152600401602060405180830381865afa158015611532573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115569190612c95565b116115a35760405162461bcd60e51b815260206004820152600c60248201527f6e6f2076616c696420706964000000000000000000000000000000000000000060448201526064016104e2565b604051631c96a19760e31b8152600481018390527f00000000000000000000000072a42e8a344eb66aca9ed13d5c633731cf54eeea6001600160a01b03169063e4b50cb890602401602060405180830381865afa158015611608573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162c9190612c0a565b90507f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a6756001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561168c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b09190612c0a565b6001600160a01b0316816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171b9190612c0a565b6001600160a01b0316146117975760405162461bcd60e51b815260206004820152602f60248201527f4661726d5a61707065723a20496e636f6d70617469626c65206c69717569646960448201527f7479207061697220666163746f7279000000000000000000000000000000000060648201526084016104e2565b919050565b6000806117aa600287612e13565b60405163149c1f6360e21b8152600481018290526024810187905260448101869052606481018590529091506000906001600160a01b037f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a67516906352707d8c90608401602060405180830381865afa15801561182a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184e9190612c95565b905060006001600160a01b037f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a6751663ad615dec8461188c818b612e35565b611896868b612e48565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa1580156118df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119039190612c95565b905061192d81836119148680612e5b565b61191e9190612e5b565b6119289190612e13565b612866565b6119379089612e48565b98975050505050505050565b6000546001600160a01b031633146107f25760405163118cdaa760e01b81523360048201526024016104e2565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038481166024830152838116604483015260648201839052610a8c9186918216906323b872dd906084015b604051602081830303815290604052915060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612918565b6000611a5f846114d1565b9050600080826001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611aa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ac69190612c45565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691507f00000000000000000000000000000000000000000000000000000000000003e882118015611b3957507f00000000000000000000000000000000000000000000000000000000000003e881115b611bab5760405162461bcd60e51b815260206004820152602b60248201527f4661726d5a61707065723a204c6971756964697479207061697220726573657260448201527f76657320746f6f206c6f7700000000000000000000000000000000000000000060648201526084016104e2565b6000846001600160a01b0316846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611bf5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c199190612c0a565b6001600160a01b03161490508080611ca35750846001600160a01b0316846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c989190612c0a565b6001600160a01b0316145b611d155760405162461bcd60e51b815260206004820152603560248201527f4661726d5a61707065723a20496e70757420746f6b656e206e6f74207072657360448201527f656e7420696e206c69717569646974792070616972000000000000000000000060648201526084016104e2565b6040805160028082526060820183526000926020830190803683370190505090508581600081518110611d4a57611d4a612cc4565b60200260200101906001600160a01b031690816001600160a01b03168152505081611dd657846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd19190612c0a565b611e38565b846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e14573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e389190612c0a565b81600181518110611e4b57611e4b612cc4565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b81523060048201526000918816906370a0823190602401602060405180830381865afa158015611ea0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ec49190612c95565b905060008315611f1957611f128287878a6001600160a01b03166369e154046040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d6000803e3d6000fd5b9050611f60565b611f5d8286888a6001600160a01b03166369e154046040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d6000803e3d6000fd5b90505b611f768360008151811061127357611273612cc4565b6040516338ed173960e01b81526000906001600160a01b037f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a67516906338ed173990611fcd9085908e90899030904290600401612cda565b6000604051808303816000875af1158015611fec573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526120149190810190612d4b565b905061202c8460018151811061127357611273612cc4565b60007f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a6756001600160a01b031663e8e337008660008151811061207057612070612cc4565b60200260200101518760018151811061208b5761208b612cc4565b6020026020010151856000815181106120a6576120a6612cc4565b6020026020010151886120b99190612e48565b866001815181106120cc576120cc612cc4565b60209081029190910101516040516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526044830152606482015260016084820181905260a48201523060c48201524260e4820152610104016060604051808303816000875af115801561214b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216f9190612e72565b9250505061219d897f00000000000000000000000072a42e8a344eb66aca9ed13d5c633731cf54eeea61277b565b6040516363bee36960e01b8152600481018d9052602481018290523360448201527f00000000000000000000000072a42e8a344eb66aca9ed13d5c633731cf54eeea6001600160a01b0316906363bee36990606401600060405180830381600087803b15801561220c57600080fd5b505af1158015612220573d6000803e3d6000fd5b5050505061222d856124dc565b604080518281523360208201526001600160a01b038c16918e917f9b5607cdd9256c448f093ce5dada1c5fae6043185c03da7ca94051577678d72a910160405180910390a3505050505050505050505050565b60008190507f00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a6756001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa15801561168c573d6000803e3d6000fd5b6040516370a0823160e01b815230600482015260009081906123679085906001600160a01b038216906370a0823190602401602060405180830381865afa158015612332573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123569190612c95565b6001600160a01b038716919061274a565b60405163226bf2d160e21b81526001600160a01b0384811660048301528516906389afcb449060240160408051808303816000875af11580156123ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123d29190612ea0565b90925090507f00000000000000000000000000000000000000000000000000000000000003e88210156124565760405162461bcd60e51b815260206004820152602660248201527f556e69737761705632526f757465723a20494e53554646494349454e545f415f604482015265105353d5539560d21b60648201526084016104e2565b7f00000000000000000000000000000000000000000000000000000000000003e88110156124d55760405162461bcd60e51b815260206004820152602660248201527f556e69737761705632526f757465723a20494e53554646494349454e545f425f604482015265105353d5539560d21b60648201526084016104e2565b9250929050565b6000805b8251811015612745578281815181106124fb576124fb612cc4565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561254b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061256f9190612c95565b91508115612733577f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad386001600160a01b03168382815181106125b3576125b3612cc4565b60200260200101516001600160a01b0316036126fc57604051632e1a7d4d60e01b8152600481018390527f000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad386001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561262b57600080fd5b505af115801561263f573d6000803e3d6000fd5b50506040805160008082526020820192839052935033925085916126639190612ec4565b60006040518083038185875af1925050503d80600081146126a0576040519150601f19603f3d011682016040523d82523d6000602084013e6126a5565b606091505b50509050806126f65760405162461bcd60e51b815260206004820152601f60248201527f4661726d5a61707065723a20455448207472616e73666572206661696c65640060448201526064016104e2565b50612733565b612733338385848151811061271357612713612cc4565b60200260200101516001600160a01b031661274a9092919063ffffffff16565b8061273d81612ef3565b9150506124e0565b505050565b6040516001600160a01b0383811660248301526044820183905261274591859182169063a9059cbb90606401611a0d565b604051636eb1769f60e11b81523060048201526001600160a01b03828116602483015283169063dd62ed3e90604401602060405180830381865afa1580156127c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127eb9190612c95565b600003610fcd5760405163095ea7b360e01b81526001600160a01b038281166004830152600019602483015283169063095ea7b3906044016020604051808303816000875af1158015612842573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127459190612f0c565b60b58171010000000000000000000000000000000000811061288d5760409190911b9060801c5b690100000000000000000081106128a95760209190911b9060401c5b6501000000000081106128c15760109190911b9060201c5b630100000081106128d75760089190911b9060101c5b62010000010260121c80820401600190811c80830401811c80830401811c80830401811c80830401811c80830401811c80830401901c908190048111900390565b600061292d6001600160a01b0384168361297b565b905080516000141580156129525750808060200190518101906129509190612f0c565b155b1561274557604051635274afe760e01b81526001600160a01b03841660048201526024016104e2565b606061298983836000612992565b90505b92915050565b6060814710156129b75760405163cd78605960e01b81523060048201526024016104e2565b600080856001600160a01b031684866040516129d39190612ec4565b60006040518083038185875af1925050503d8060008114612a10576040519150601f19603f3d011682016040523d82523d6000602084013e612a15565b606091505b5091509150612a25868383612a31565b925050505b9392505050565b606082612a4657612a4182612a8d565b612a2a565b8151158015612a5d57506001600160a01b0384163b155b15612a8657604051639996b31560e01b81526001600160a01b03851660048201526024016104e2565b5080612a2a565b805115612a9d5780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b634e487b7160e01b600052600160045260246000fd5b6001600160a01b038116811461100c57600080fd5b600080600060608486031215612af657600080fd5b833592506020840135612b0881612acc565b929592945050506040919091013590565b60008060008060808587031215612b2f57600080fd5b84359350602085013592506040850135612b4881612acc565b9396929550929360600135925050565b60008060008060808587031215612b6e57600080fd5b8435612b7981612acc565b966020860135965060408601359560600135945092505050565b600060208284031215612ba557600080fd5b8135612a2a81612acc565b60008060008060808587031215612bc657600080fd5b8435612bd181612acc565b9350602085013592506040850135612b4881612acc565b60008060408385031215612bfb57600080fd5b50508035926020909101359150565b600060208284031215612c1c57600080fd5b8151612a2a81612acc565b80516dffffffffffffffffffffffffffff8116811461179757600080fd5b600080600060608486031215612c5a57600080fd5b612c6384612c27565b9250612c7160208501612c27565b9150604084015163ffffffff81168114612c8a57600080fd5b809150509250925092565b600060208284031215612ca757600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015612d2a5784516001600160a01b031683529383019391830191600101612d05565b50506001600160a01b03969096166060850152505050608001529392505050565b60006020808385031215612d5e57600080fd5b825167ffffffffffffffff80821115612d7657600080fd5b818501915085601f830112612d8a57600080fd5b815181811115612d9c57612d9c612cae565b8060051b604051601f19603f83011681018181108582111715612dc157612dc1612cae565b604052918252848201925083810185019188831115612ddf57600080fd5b938501935b8285101561193757845184529385019392850192612de4565b634e487b7160e01b600052601160045260246000fd5b600082612e3057634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561298c5761298c612dfd565b8181038181111561298c5761298c612dfd565b808202811582820484141761298c5761298c612dfd565b600080600060608486031215612e8757600080fd5b8351925060208401519150604084015190509250925092565b60008060408385031215612eb357600080fd5b505080516020909101519092909150565b6000825160005b81811015612ee55760208186018101518583015201612ecb565b506000920191825250919050565b600060018201612f0557612f05612dfd565b5060010190565b600060208284031215612f1e57600080fd5b81518015158114612a2a57600080fdfea2646970667358221220feb5205d6f7d552df8c4bb26c1e14c02212754c8423581a9302836e54c1184f764736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a67500000000000000000000000072a42e8a344eb66aca9ed13d5c633731cf54eeea000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000000000000000000000000000000000000000003e80000000000000000000000004a3723b6e427ecbd90f2848d6df9381a676a02b9
-----Decoded View---------------
Arg [0] : router (address): 0x49E51a0cba6763eE4f14C60B30c044dbD487a675
Arg [1] : masterchef (address): 0x72a42e8a344eB66ACA9eD13d5C633731cF54EeEa
Arg [2] : wNative (address): 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38
Arg [3] : minimumAmount (uint256): 1000
Arg [4] : admin (address): 0x4A3723B6e427Ecbd90f2848d6dF9381A676a02b9
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000049e51a0cba6763ee4f14c60b30c044dbd487a675
Arg [1] : 00000000000000000000000072a42e8a344eb66aca9ed13d5c633731cf54eeea
Arg [2] : 000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Arg [3] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [4] : 0000000000000000000000004a3723b6e427ecbd90f2848d6df9381a676a02b9
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.