Source Code
Latest 25 from a total of 7,853 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Withdraw And Har... | 369486408 | 167 days ago | IN | 0 ETH | 0.00000196 | ||||
| Withdraw And Har... | 369485679 | 167 days ago | IN | 0 ETH | 0.00000206 | ||||
| Withdraw And Har... | 359257550 | 197 days ago | IN | 0 ETH | 0.0000016 | ||||
| Withdraw And Har... | 358839406 | 198 days ago | IN | 0 ETH | 0.0000167 | ||||
| Withdraw And Har... | 358839311 | 198 days ago | IN | 0 ETH | 0.00001755 | ||||
| Withdraw And Har... | 356618175 | 204 days ago | IN | 0 ETH | 0.0000054 | ||||
| Withdraw And Har... | 356618142 | 204 days ago | IN | 0 ETH | 0.00000566 | ||||
| Withdraw And Har... | 353096682 | 215 days ago | IN | 0 ETH | 0.00000161 | ||||
| Withdraw And Har... | 328815061 | 285 days ago | IN | 0 ETH | 0.00000146 | ||||
| Withdraw And Har... | 323969628 | 299 days ago | IN | 0 ETH | 0.00000297 | ||||
| Withdraw And Har... | 320945371 | 308 days ago | IN | 0 ETH | 0.00000126 | ||||
| Withdraw And Har... | 299083370 | 372 days ago | IN | 0 ETH | 0.00000219 | ||||
| Withdraw And Har... | 297938193 | 375 days ago | IN | 0 ETH | 0.00000403 | ||||
| Withdraw And Har... | 297938148 | 375 days ago | IN | 0 ETH | 0.00000413 | ||||
| Withdraw And Har... | 297860533 | 375 days ago | IN | 0 ETH | 0.00000869 | ||||
| Withdraw And Har... | 296146429 | 380 days ago | IN | 0 ETH | 0.00000234 | ||||
| Withdraw And Har... | 295552796 | 382 days ago | IN | 0 ETH | 0.00000696 | ||||
| Withdraw And Har... | 294132828 | 386 days ago | IN | 0 ETH | 0.00000175 | ||||
| Withdraw And Har... | 290869903 | 395 days ago | IN | 0 ETH | 0.00000309 | ||||
| Withdraw And Har... | 288936068 | 401 days ago | IN | 0 ETH | 0.00000253 | ||||
| Withdraw And Har... | 287091028 | 406 days ago | IN | 0 ETH | 0.00000302 | ||||
| Withdraw And Har... | 283094670 | 418 days ago | IN | 0 ETH | 0.00010472 | ||||
| Withdraw And Har... | 278181504 | 432 days ago | IN | 0 ETH | 0.00000406 | ||||
| Withdraw And Har... | 276879715 | 436 days ago | IN | 0 ETH | 0.00000682 | ||||
| Withdraw And Har... | 276879549 | 436 days ago | IN | 0 ETH | 0.00000677 |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
MiniChefV2
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.8.20;
/// @notice The (older) MasterChef contract gives out a constant number of SUSHI tokens per block.
/// It is the only address with minting rights for SUSHI.
/// The idea for this MasterChef V2 (MCV2) contract is therefore to be the owner of a dummy token
/// that is deposited into the MasterChef V1 (MCV1) contract.
/// The allocation point for this pool on MCV1 is the total allocation point for all pools that receive double incentives.
import {IERC20} from "src/Sushi/IERC20.sol";
import {SignedSafeMath} from "src/Sushi/SignedSafeMath.sol";
import {BoringMath, BoringMath128} from "src/Sushi/BoringMath.sol";
import {BoringERC20} from "src/Sushi/BoringERC20.sol";
import {Operable, Governable} from "src/common/Operable.sol";
import {BoringBatchable} from "src/Sushi/BoringBatchable.sol";
import {IMigratorChef} from "src/Sushi/IMigratorChef.sol";
import {IRewarder} from "src/Sushi/IRewarder.sol";
contract MiniChefV2 is Operable, BoringBatchable {
using BoringMath for uint256;
using BoringMath128 for uint128;
using BoringERC20 for IERC20;
using SignedSafeMath for int256;
/// @notice Info of each MCV2 user.
/// `amount` LP token amount the user has provided.
/// `rewardDebt` The amount of SUSHI entitled to the user.
struct UserInfo {
uint256 amount;
int256 rewardDebt;
}
/// @notice Info of each MCV2 pool.
/// `allocPoint` The amount of allocation points assigned to the pool.
/// Also known as the amount of SUSHI to distribute per block.
struct PoolInfo {
uint128 accSushiPerShare;
uint64 lastRewardTime;
uint64 allocPoint;
uint256 depositIncentives;
}
/// @notice Address of SUSHI contract.
IERC20 public immutable SUSHI;
// @notice The migrator contract. It has a lot of power. Can only be set through governance (owner).
IMigratorChef public migrator;
/// @notice Info of each MCV2 pool.
PoolInfo[] public poolInfo;
/// @notice Address of the LP token for each MCV2 pool.
IERC20[] public lpToken;
/// @notice Address of each `IRewarder` contract in MCV2.
IRewarder[] public rewarder;
/// @notice Info of each user that stakes LP tokens.
mapping(uint256 => mapping(address => UserInfo)) public userInfo;
/// @dev Total allocation points. Must be the sum of all allocation points in all pools.
uint256 public totalAllocPoint;
uint256 public sushiPerSecond;
uint256 private constant ACC_SUSHI_PRECISION = 1e12;
/// @notice Extra vars
uint256 public deadline;
bool public incentivesOn;
address public incentiveReceiver;
/// @notice poolId => deposit incentives
mapping(uint256 => uint256) depositIncentives;
event Deposit(address indexed user, uint256 indexed pid, uint256 amount, address indexed to, uint256 incentive);
event Withdraw(address indexed user, uint256 indexed pid, uint256 amount, address indexed to);
event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount, address indexed to);
event Harvest(address indexed user, uint256 indexed pid, uint256 amount);
event LogPoolAddition(uint256 indexed pid, uint256 allocPoint, IERC20 indexed lpToken, IRewarder indexed rewarder);
event LogSetPool(uint256 indexed pid, uint256 allocPoint, IRewarder indexed rewarder, bool overwrite);
event LogUpdatePool(uint256 indexed pid, uint64 lastRewardTime, uint256 lpSupply, uint256 accSushiPerShare);
event LogSushiPerSecond(uint256 sushiPerSecond);
/// @param _sushi The SUSHI token contract address.
constructor(IERC20 _sushi, address _incentiveReceiver) Governable(msg.sender) {
SUSHI = _sushi;
deadline = 1706745599;
incentivesOn = true;
incentiveReceiver = _incentiveReceiver;
}
/// @notice Returns the number of MCV2 pools.
function poolLength() public view returns (uint256 pools) {
pools = poolInfo.length;
}
/// @notice Add a new LP to the pool. Can only be called by the owner.
/// DO NOT add the same LP token more than once. Rewards will be messed up if you do.
/// @param allocPoint AP of the new pool.
/// @param _lpToken Address of the LP ERC-20 token.
/// @param _rewarder Address of the rewarder delegate.
function add(uint256 allocPoint, IERC20 _lpToken, IRewarder _rewarder, uint256 _depositIncentives)
public
onlyGovernor
{
totalAllocPoint = totalAllocPoint.add(allocPoint);
lpToken.push(_lpToken);
rewarder.push(_rewarder);
poolInfo.push(
PoolInfo({
allocPoint: allocPoint.to64(),
lastRewardTime: block.timestamp.to64(),
accSushiPerShare: 0,
depositIncentives: _depositIncentives
})
);
emit LogPoolAddition(lpToken.length.sub(1), allocPoint, _lpToken, _rewarder);
}
/// @notice Update the given pool's SUSHI allocation point and `IRewarder` contract. Can only be called by the owner.
/// @param _pid The index of the pool. See `poolInfo`.
/// @param _allocPoint New AP of the pool.
/// @param _rewarder Address of the rewarder delegate.
/// @param overwrite True if _rewarder should be `set`. Otherwise `_rewarder` is ignored.
function set(uint256 _pid, uint256 _allocPoint, IRewarder _rewarder, bool overwrite)
public
onlyGovernorOrOperator
{
totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
poolInfo[_pid].allocPoint = _allocPoint.to64();
if (overwrite) rewarder[_pid] = _rewarder;
emit LogSetPool(_pid, _allocPoint, overwrite ? _rewarder : rewarder[_pid], overwrite);
}
/// @notice Sets the sushi per second to be distributed. Can only be called by the owner.
/// @param _sushiPerSecond The amount of Sushi to be distributed per second.
function setSushiPerSecond(uint256 _sushiPerSecond) public onlyGovernor {
sushiPerSecond = _sushiPerSecond;
emit LogSushiPerSecond(_sushiPerSecond);
}
/// @notice Toggle incentives, if is it true it mean incentives are ON
function toggleIncentives() public onlyGovernor {
incentivesOn = !incentivesOn;
}
/// @notice Sets the rewards deadline. Can only be called by the owner.
/// @param _deadline The timestmap for rewards deadline.
function setDeadline(uint256 _deadline) public onlyGovernor {
deadline = _deadline;
}
/// @notice Set the `migrator` contract. Can only be called by the owner.
/// @param _migrator The contract address to set.
function setMigrator(IMigratorChef _migrator) public onlyGovernor {
migrator = _migrator;
}
/// @notice Migrate LP token to another LP contract through the `migrator` contract.
/// @param _pid The index of the pool. See `poolInfo`.
function migrate(uint256 _pid) public {
require(address(migrator) != address(0), "MasterChefV2: no migrator set");
IERC20 _lpToken = lpToken[_pid];
uint256 bal = _lpToken.balanceOf(address(this));
_lpToken.approve(address(migrator), bal);
IERC20 newLpToken = migrator.migrate(_lpToken);
require(bal == newLpToken.balanceOf(address(this)), "MasterChefV2: migrated balance must match");
lpToken[_pid] = newLpToken;
}
/// @notice View function to see pending SUSHI on frontend.
/// @param _pid The index of the pool. See `poolInfo`.
/// @param _user Address of user.
/// @return pending SUSHI reward for a given user.
function pendingSushi(uint256 _pid, address _user) external view returns (uint256 pending) {
PoolInfo memory pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 accSushiPerShare = pool.accSushiPerShare;
uint256 lpSupply = lpToken[_pid].balanceOf(address(this));
if (block.timestamp > pool.lastRewardTime && lpSupply != 0) {
uint256 time = block.timestamp.sub(pool.lastRewardTime);
uint256 sushiReward = time.mul(sushiPerSecond).mul(pool.allocPoint) / totalAllocPoint;
accSushiPerShare = accSushiPerShare.add(sushiReward.mul(ACC_SUSHI_PRECISION) / lpSupply);
}
pending = int256(user.amount.mul(accSushiPerShare) / ACC_SUSHI_PRECISION).sub(user.rewardDebt).toUInt256();
}
/// @notice Update reward variables for all pools. Be careful of gas spending!
/// @param pids Pool IDs of all to be updated. Make sure to update all active pools.
function massUpdatePools(uint256[] calldata pids) external {
uint256 len = pids.length;
for (uint256 i = 0; i < len; ++i) {
updatePool(pids[i]);
}
}
/// @notice Update reward variables of the given pool.
/// @param pid The index of the pool. See `poolInfo`.
/// @return pool Returns the pool that was updated.
function updatePool(uint256 pid) public returns (PoolInfo memory pool) {
pool = poolInfo[pid];
if (block.timestamp >= deadline) {
setSushiPerSecond(0);
}
if (block.timestamp > pool.lastRewardTime) {
uint256 lpSupply = lpToken[pid].balanceOf(address(this));
if (lpSupply > 0) {
uint256 time = block.timestamp.sub(pool.lastRewardTime);
uint256 sushiReward = time.mul(sushiPerSecond).mul(pool.allocPoint) / totalAllocPoint;
pool.accSushiPerShare =
pool.accSushiPerShare.add((sushiReward.mul(ACC_SUSHI_PRECISION) / lpSupply).to128());
}
pool.lastRewardTime = block.timestamp.to64();
poolInfo[pid] = pool;
emit LogUpdatePool(pid, pool.lastRewardTime, lpSupply, pool.accSushiPerShare);
}
}
/// @notice Deposit LP tokens to MCV2 for SUSHI allocation.
/// @param pid The index of the pool. See `poolInfo`.
/// @param amount LP token amount to deposit.
/// @param to The receiver of `amount` deposit benefit.
function deposit(uint256 pid, uint256 amount, address to) public {
PoolInfo memory pool = updatePool(pid);
UserInfo storage user = userInfo[pid][to];
uint256 incentive;
if (incentivesOn && pool.depositIncentives != 0 && incentiveReceiver != address(0)) {
incentive = amount.mul(pool.depositIncentives) / ACC_SUSHI_PRECISION;
lpToken[pid].safeTransferFrom(msg.sender, incentiveReceiver, incentive);
}
amount = amount - incentive;
// Effects
user.amount = user.amount.add(amount);
user.rewardDebt = user.rewardDebt.add(int256(amount.mul(pool.accSushiPerShare) / ACC_SUSHI_PRECISION));
// Interactions
IRewarder _rewarder = rewarder[pid];
if (address(_rewarder) != address(0)) {
_rewarder.onSushiReward(pid, to, to, 0, user.amount);
}
lpToken[pid].safeTransferFrom(msg.sender, address(this), amount);
emit Deposit(msg.sender, pid, amount, to, incentive);
}
/// @notice Withdraw LP tokens from MCV2.
/// @param pid The index of the pool. See `poolInfo`.
/// @param amount LP token amount to withdraw.
/// @param to Receiver of the LP tokens.
function withdraw(uint256 pid, uint256 amount, address to) public {
PoolInfo memory pool = updatePool(pid);
UserInfo storage user = userInfo[pid][msg.sender];
// Effects
user.rewardDebt = user.rewardDebt.sub(int256(amount.mul(pool.accSushiPerShare) / ACC_SUSHI_PRECISION));
user.amount = user.amount.sub(amount);
// Interactions
IRewarder _rewarder = rewarder[pid];
if (address(_rewarder) != address(0)) {
_rewarder.onSushiReward(pid, msg.sender, to, 0, user.amount);
}
lpToken[pid].safeTransfer(to, amount);
emit Withdraw(msg.sender, pid, amount, to);
}
/// @notice Harvest proceeds for transaction sender to `to`.
/// @param pid The index of the pool. See `poolInfo`.
/// @param to Receiver of SUSHI rewards.
function harvest(uint256 pid, address to) public {
PoolInfo memory pool = updatePool(pid);
UserInfo storage user = userInfo[pid][msg.sender];
int256 accumulatedSushi = int256(user.amount.mul(pool.accSushiPerShare) / ACC_SUSHI_PRECISION);
uint256 _pendingSushi = accumulatedSushi.sub(user.rewardDebt).toUInt256();
// Effects
user.rewardDebt = accumulatedSushi;
// Interactions
if (_pendingSushi != 0) {
SUSHI.safeTransfer(to, _pendingSushi);
}
IRewarder _rewarder = rewarder[pid];
if (address(_rewarder) != address(0)) {
_rewarder.onSushiReward(pid, msg.sender, to, _pendingSushi, user.amount);
}
emit Harvest(msg.sender, pid, _pendingSushi);
}
/// @notice Withdraw LP tokens from MCV2 and harvest proceeds for transaction sender to `to`.
/// @param pid The index of the pool. See `poolInfo`.
/// @param amount LP token amount to withdraw.
/// @param to Receiver of the LP tokens and SUSHI rewards.
function withdrawAndHarvest(uint256 pid, uint256 amount, address to) public {
PoolInfo memory pool = updatePool(pid);
UserInfo storage user = userInfo[pid][msg.sender];
int256 accumulatedSushi = int256(user.amount.mul(pool.accSushiPerShare) / ACC_SUSHI_PRECISION);
uint256 _pendingSushi = accumulatedSushi.sub(user.rewardDebt).toUInt256();
// Effects
user.rewardDebt = accumulatedSushi.sub(int256(amount.mul(pool.accSushiPerShare) / ACC_SUSHI_PRECISION));
user.amount = user.amount.sub(amount);
// Interactions
SUSHI.safeTransfer(to, _pendingSushi);
IRewarder _rewarder = rewarder[pid];
if (address(_rewarder) != address(0)) {
_rewarder.onSushiReward(pid, msg.sender, to, _pendingSushi, user.amount);
}
lpToken[pid].safeTransfer(to, amount);
emit Withdraw(msg.sender, pid, amount, to);
emit Harvest(msg.sender, pid, _pendingSushi);
}
/// @notice Withdraw without caring about rewards. EMERGENCY ONLY.
/// @param pid The index of the pool. See `poolInfo`.
/// @param to Receiver of the LP tokens.
function emergencyWithdraw(uint256 pid, address to) public {
UserInfo storage user = userInfo[pid][msg.sender];
uint256 amount = user.amount;
user.amount = 0;
user.rewardDebt = 0;
IRewarder _rewarder = rewarder[pid];
if (address(_rewarder) != address(0)) {
_rewarder.onSushiReward(pid, msg.sender, to, 0, 0);
}
// Note: transfer can fail or succeed if `amount` is zero.
lpToken[pid].safeTransfer(to, amount);
emit EmergencyWithdraw(msg.sender, pid, amount, to);
}
/**
* @notice Moves assets from the strategy to `_to`
* @param _assets An array of IERC20 compatible tokens to move out from the strategy
* @param _withdrawNative `true` if we want to move the native asset from the strategy
*/
function emergencyWithdraw(address _to, address[] memory _assets, bool _withdrawNative) external onlyGovernor {
uint256 assetsLength = _assets.length;
for (uint256 i = 0; i < assetsLength; i++) {
IERC20 asset = IERC20(_assets[i]);
uint256 assetBalance = asset.balanceOf(address(this));
if (assetBalance > 0) {
// Transfer the ERC20 tokens
asset.safeTransfer(_to, assetBalance);
}
unchecked {
++i;
}
}
uint256 nativeBalance = address(this).balance;
// Nothing else to do
if (_withdrawNative && nativeBalance > 0) {
// Transfer the native currency
(bool sent,) = payable(_to).call{value: nativeBalance}("");
if (!sent) {
revert FailSendETH();
}
}
emit EmergencyWithdrawal(msg.sender, _to, _assets, _withdrawNative ? nativeBalance : 0);
}
/**
* @notice Update pool deposit incentives
* @param pid Pool id
* @param _depositIncentives amount of incentives when deposit
*/
function updatePoolIncentive(uint256 pid, uint256 _depositIncentives) external onlyGovernor {
poolInfo[pid].depositIncentives = _depositIncentives;
}
event EmergencyWithdrawal(address indexed caller, address indexed receiver, address[] tokens, uint256 nativeBalanc);
error FailSendETH();
}// File @boringcrypto/boring-solidity/contracts/interfaces/[email protected] pragma solidity 0.8.20; interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); // EIP 2612 function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; }
// File contracts/libraries/SignedSafeMath.sol
pragma solidity 0.8.20;
library SignedSafeMath {
int256 private constant _INT256_MIN = -2 ** 255;
/**
* @dev Returns the multiplication of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(int256 a, int256 b) internal pure returns (int256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b, "SignedSafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two signed integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0, "SignedSafeMath: division by zero");
require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");
int256 c = a / b;
return c;
}
/**
* @dev Returns the subtraction of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");
return c;
}
/**
* @dev Returns the addition of two signed integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");
return c;
}
function toUInt256(int256 a) internal pure returns (uint256) {
require(a >= 0, "Integer < 0");
return uint256(a);
}
}// File @boringcrypto/boring-solidity/contracts/libraries/[email protected] // SPDX-License-Identifier: MIT pragma solidity 0.8.20; library BoringMath { function add(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint256 a, uint256 b) internal pure returns (uint256 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } function mul(uint256 a, uint256 b) internal pure returns (uint256 c) { require(b == 0 || (c = a * b) / b == a, "BoringMath: Mul Overflow"); } function to128(uint256 a) internal pure returns (uint128 c) { require(a <= type(uint128).max, "BoringMath: uint128 Overflow"); c = uint128(a); } function to64(uint256 a) internal pure returns (uint64 c) { require(a <= type(uint64).max, "BoringMath: uint64 Overflow"); c = uint64(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= type(uint32).max, "BoringMath: uint32 Overflow"); c = uint32(a); } } library BoringMath128 { function add(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint128 a, uint128 b) internal pure returns (uint128 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } library BoringMath64 { function add(uint64 a, uint64 b) internal pure returns (uint64 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint64 a, uint64 b) internal pure returns (uint64 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } } library BoringMath32 { function add(uint32 a, uint32 b) internal pure returns (uint32 c) { require((c = a + b) >= b, "BoringMath: Add Overflow"); } function sub(uint32 a, uint32 b) internal pure returns (uint32 c) { require((c = a - b) <= a, "BoringMath: Underflow"); } }
// File @boringcrypto/boring-solidity/contracts/libraries/[email protected] pragma solidity 0.8.20; import {IERC20} from "src/Sushi/IERC20.sol"; library BoringERC20 { function safeSymbol(IERC20 token) internal view returns (string memory) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x95d89b41)); return success && data.length > 0 ? abi.decode(data, (string)) : "???"; } function safeName(IERC20 token) internal view returns (string memory) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x06fdde03)); return success && data.length > 0 ? abi.decode(data, (string)) : "???"; } function safeDecimals(IERC20 token) internal view returns (uint8) { (bool success, bytes memory data) = address(token).staticcall(abi.encodeWithSelector(0x313ce567)); return success && data.length == 32 ? abi.decode(data, (uint8)) : 18; } function safeTransfer(IERC20 token, address to, uint256 amount) internal { (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0xa9059cbb, to, amount)); require(success && (data.length == 0 || abi.decode(data, (bool))), "BoringERC20: Transfer failed"); } function safeTransferFrom(IERC20 token, address from, address to, uint256 amount) internal { (bool success, bytes memory data) = address(token).call(abi.encodeWithSelector(0x23b872dd, from, to, amount)); require(success && (data.length == 0 || abi.decode(data, (bool))), "BoringERC20: TransferFrom failed"); } }
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Governable} from "src/common/Governable.sol";
abstract contract Operable is Governable {
bytes32 public constant OPERATOR = bytes32("OPERATOR");
modifier onlyOperator() {
if (!hasRole(OPERATOR, msg.sender)) {
revert CallerIsNotOperator();
}
_;
}
modifier onlyGovernorOrOperator() {
if (!(hasRole(GOVERNOR, msg.sender) || hasRole(OPERATOR, msg.sender))) {
revert CallerIsNotAllowed();
}
_;
}
function addOperator(address _newOperator) external onlyGovernor {
_grantRole(OPERATOR, _newOperator);
emit OperatorAdded(_newOperator);
}
function removeOperator(address _operator) external onlyGovernor {
_revokeRole(OPERATOR, _operator);
emit OperatorRemoved(_operator);
}
event OperatorAdded(address _newOperator);
event OperatorRemoved(address _operator);
error CallerIsNotOperator();
error CallerIsNotAllowed();
}// File @boringcrypto/boring-solidity/contracts/[email protected] // Audit on 5-Jan-2021 by Keno and BoringCrypto // P1 - P3: OK pragma solidity 0.8.20; // solhint-disable avoid-low-level-calls // T1 - T4: OK import {IERC20} from "src/Sushi/IERC20.sol"; contract BaseBoringBatchable { function _getRevertMsg(bytes memory _returnData) internal pure returns (string memory) { // If the _res length is less than 68, then the transaction failed silently (without a revert message) if (_returnData.length < 68) return "Transaction reverted silently"; assembly { // Slice the sighash. _returnData := add(_returnData, 0x04) } return abi.decode(_returnData, (string)); // All that remains is the revert string } // F3 - F9: OK // F1: External is ok here because this is the batch function, adding it to a batch makes no sense // F2: Calls in the batch may be payable, delegatecall operates in the same context, so each call in the batch has access to msg.value // C1 - C21: OK // C3: The length of the loop is fully under user control, so can't be exploited // C7: Delegatecall is only used on the same contract, so it's safe function batch(bytes[] calldata calls, bool revertOnFail) external payable returns (bool[] memory successes, bytes[] memory results) { // Interactions successes = new bool[](calls.length); results = new bytes[](calls.length); for (uint256 i = 0; i < calls.length; i++) { (bool success, bytes memory result) = address(this).delegatecall(calls[i]); require(success || !revertOnFail, _getRevertMsg(result)); successes[i] = success; results[i] = result; } } } // T1 - T4: OK contract BoringBatchable is BaseBoringBatchable { // F1 - F9: OK // F6: Parameters can be used front-run the permit and the user's permit will fail (due to nonce or other revert) // if part of a batch this could be used to grief once as the second call would not need the permit // C1 - C21: OK function permitToken( IERC20 token, address from, address to, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public { // Interactions // X1 - X5 token.permit(from, to, amount, deadline, v, r, s); } }
// File contracts/MiniChefV2.sol
pragma solidity 0.8.20;
import {IERC20} from "src/Sushi/IERC20.sol";
interface IMigratorChef {
// Take the current LP token address and return the new LP token address.
// Migrator should have full access to the caller's LP token.
function migrate(IERC20 token) external returns (IERC20);
}// File contracts/interfaces/IRewarder.sol
pragma solidity 0.8.20;
import {IERC20} from "src/Sushi/IERC20.sol";
interface IRewarder {
function onSushiReward(uint256 pid, address user, address recipient, uint256 sushiAmount, uint256 newLpAmount)
external;
function pendingTokens(uint256 pid, address user, uint256 sushiAmount)
external
view
returns (IERC20[] memory, uint256[] memory);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {AccessControl} from "openzeppelin-contracts/contracts/access/AccessControl.sol";
abstract contract Governable is AccessControl {
bytes32 public constant GOVERNOR = bytes32("GOVERNOR");
constructor(address _governor) {
_grantRole(GOVERNOR, _governor);
}
modifier onlyGovernor() {
_onlyGovernor();
_;
}
function updateGovernor(address _newGovernor) external onlyGovernor {
_revokeRole(GOVERNOR, msg.sender);
_grantRole(GOVERNOR, _newGovernor);
emit GovernorUpdated(msg.sender, _newGovernor);
}
function _onlyGovernor() private view {
if (!hasRole(GOVERNOR, msg.sender)) {
revert CallerIsNotGovernor();
}
}
event GovernorUpdated(address _oldGovernor, address _newGovernor);
error CallerIsNotGovernor();
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `_msgSender()` is missing `role`.
* Overriding this function changes the behavior of the {onlyRole} modifier.
*
* Format of the revert message is described in {_checkRole}.
*
* _Available since v4.6._
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* May emit a {RoleGranted} event.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"solmate/=lib/solmate/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"ds-test/=lib/solmate/lib/ds-test/src/",
"openzeppelin-upgradeable-contracts/=lib/openzeppelin-contracts-upgradeable/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IERC20","name":"_sushi","type":"address"},{"internalType":"address","name":"_incentiveReceiver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CallerIsNotAllowed","type":"error"},{"inputs":[],"name":"CallerIsNotGovernor","type":"error"},{"inputs":[],"name":"CallerIsNotOperator","type":"error"},{"inputs":[],"name":"FailSendETH","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"incentive","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address[]","name":"tokens","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"nativeBalanc","type":"uint256"}],"name":"EmergencyWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_oldGovernor","type":"address"},{"indexed":false,"internalType":"address","name":"_newGovernor","type":"address"}],"name":"GovernorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Harvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"},{"indexed":true,"internalType":"contract IERC20","name":"lpToken","type":"address"},{"indexed":true,"internalType":"contract IRewarder","name":"rewarder","type":"address"}],"name":"LogPoolAddition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"},{"indexed":true,"internalType":"contract IRewarder","name":"rewarder","type":"address"},{"indexed":false,"internalType":"bool","name":"overwrite","type":"bool"}],"name":"LogSetPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"sushiPerSecond","type":"uint256"}],"name":"LogSushiPerSecond","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"lastRewardTime","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"lpSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accSushiPerShare","type":"uint256"}],"name":"LogUpdatePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_newOperator","type":"address"}],"name":"OperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_operator","type":"address"}],"name":"OperatorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOVERNOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUSHI","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"contract IERC20","name":"_lpToken","type":"address"},{"internalType":"contract IRewarder","name":"_rewarder","type":"address"},{"internalType":"uint256","name":"_depositIncentives","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOperator","type":"address"}],"name":"addOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"calls","type":"bytes[]"},{"internalType":"bool","name":"revertOnFail","type":"bool"}],"name":"batch","outputs":[{"internalType":"bool[]","name":"successes","type":"bool[]"},{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"deadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"address[]","name":"_assets","type":"address[]"},{"internalType":"bool","name":"_withdrawNative","type":"bool"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentiveReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentivesOn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lpToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"pids","type":"uint256[]"}],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"migrator","outputs":[{"internalType":"contract IMigratorChef","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingSushi","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permitToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"uint128","name":"accSushiPerShare","type":"uint128"},{"internalType":"uint64","name":"lastRewardTime","type":"uint64"},{"internalType":"uint64","name":"allocPoint","type":"uint64"},{"internalType":"uint256","name":"depositIncentives","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"pools","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"removeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewarder","outputs":[{"internalType":"contract IRewarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IRewarder","name":"_rewarder","type":"address"},{"internalType":"bool","name":"overwrite","type":"bool"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_deadline","type":"uint256"}],"name":"setDeadline","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMigratorChef","name":"_migrator","type":"address"}],"name":"setMigrator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_sushiPerSecond","type":"uint256"}],"name":"setSushiPerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sushiPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleIncentives","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newGovernor","type":"address"}],"name":"updateGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"}],"name":"updatePool","outputs":[{"components":[{"internalType":"uint128","name":"accSushiPerShare","type":"uint128"},{"internalType":"uint64","name":"lastRewardTime","type":"uint64"},{"internalType":"uint64","name":"allocPoint","type":"uint64"},{"internalType":"uint256","name":"depositIncentives","type":"uint256"}],"internalType":"struct MiniChefV2.PoolInfo","name":"pool","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"_depositIncentives","type":"uint256"}],"name":"updatePoolIncentive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"int256","name":"rewardDebt","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"withdrawAndHarvest","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b506040516200385038038062003850833981016040819052620000349162000141565b336200004c6723a7ab22a92727a960c11b8262000087565b506001600160a01b039182166080526365badeff6008556009805491909216610100026001600160a81b031990911617600117905562000180565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000124576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620000e33390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6001600160a01b03811681146200013e57600080fd5b50565b600080604083850312156200015557600080fd5b8251620001628162000128565b6020840151909250620001758162000128565b809150509250929050565b6080516136a6620001aa6000396000818161076a01528181610b440152611f4901526136a66000f3fe60806040526004361061025c5760003560e01c80637c516e9411610144578063a217fddf116100b6578063c4ade30b1161007a578063c4ade30b146107cc578063d1abb907146107f1578063d2423b5114610811578063d547741f14610832578063d8e96c2314610852578063f9aee4601461087257600080fd5b8063a217fddf1461072e578063a5a362d614610743578063ab560e1014610758578063ac8a584a1461078c578063c346253d146107ac57600080fd5b806391d148541161010857806391d148541461064557806393f1a40b14610665578063983d2737146106b95780639870d7fe146106d85780639baf58c3146106f8578063a06e408b1461071857600080fd5b80637c516e94146105a55780637cd07e47146105c557806388bba42f146105e55780638dbdbe6d146106055780639195ebc61461062557600080fd5b806329dcb0cf116101dd57806351eb05a6116101a157806351eb05a61461048a57806357a5b58c146104f457806362f384ad146105145780636cdfa1b7146105345780636dc0ae221461054e57806378ed5d1f1461056d57600080fd5b806329dcb0cf146103f45780632f2ff15d1461040a5780632f940c701461042a57806336568abe1461044a578063454b06081461046a57600080fd5b806318fccc761161022457806318fccc7614610344578063195199f614610364578063195426ec1461038457806323cf3118146103a4578063248a9ca3146103c457600080fd5b806301ffc9a714610261578063081e3eda146102965780630ad58d2f146102b55780631526fe27146102d757806317caf6f11461032e575b600080fd5b34801561026d57600080fd5b5061028161027c366004612dd5565b610892565b60405190151581526020015b60405180910390f35b3480156102a257600080fd5b506002545b60405190815260200161028d565b3480156102c157600080fd5b506102d56102d0366004612e14565b6108c9565b005b3480156102e357600080fd5b506102f76102f2366004612e4d565b610a62565b604080516001600160801b039590951685526001600160401b0393841660208601529190921690830152606082015260800161028d565b34801561033a57600080fd5b506102a760065481565b34801561035057600080fd5b506102d561035f366004612e66565b610ab4565b34801561037057600080fd5b506102d561037f366004612e4d565b610c45565b34801561039057600080fd5b506102a761039f366004612e66565b610c52565b3480156103b057600080fd5b506102d56103bf366004612e96565b610e57565b3480156103d057600080fd5b506102a76103df366004612e4d565b60009081526020819052604090206001015490565b34801561040057600080fd5b506102a760085481565b34801561041657600080fd5b506102d5610425366004612e66565b610e81565b34801561043657600080fd5b506102d5610445366004612e66565b610eab565b34801561045657600080fd5b506102d5610465366004612e66565b610fda565b34801561047657600080fd5b506102d5610485366004612e4d565b61105d565b34801561049657600080fd5b506104aa6104a5366004612e4d565b61133f565b6040805182516001600160801b031681526020808401516001600160401b03908116918301919091528383015116918101919091526060918201519181019190915260800161028d565b34801561050057600080fd5b506102d561050f366004612efe565b61161f565b34801561052057600080fd5b506102d561052f366004612e96565b611663565b34801561054057600080fd5b506009546102819060ff1681565b34801561055a57600080fd5b506102a76723a7ab22a92727a960c11b81565b34801561057957600080fd5b5061058d610588366004612e4d565b6116da565b6040516001600160a01b03909116815260200161028d565b3480156105b157600080fd5b506102d56105c0366004612f3f565b611704565b3480156105d157600080fd5b5060015461058d906001600160a01b031681565b3480156105f157600080fd5b506102d5610600366004612fe1565b611796565b34801561061157600080fd5b506102d5610620366004612e14565b611952565b34801561063157600080fd5b506102d5610640366004613071565b611b89565b34801561065157600080fd5b50610281610660366004612e66565b611d40565b34801561067157600080fd5b506106a4610680366004612e66565b60056020908152600092835260408084209091529082529020805460019091015482565b6040805192835260208301919091520161028d565b3480156106c557600080fd5b506102a76727a822a920aa27a960c11b81565b3480156106e457600080fd5b506102d56106f3366004612e96565b611d69565b34801561070457600080fd5b506102d5610713366004612e4d565b611dbf565b34801561072457600080fd5b506102a760075481565b34801561073a57600080fd5b506102a7600081565b34801561074f57600080fd5b506102d5611dfc565b34801561076457600080fd5b5061058d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561079857600080fd5b506102d56107a7366004612e96565b611e18565b3480156107b857600080fd5b5061058d6107c7366004612e4d565b611e6e565b3480156107d857600080fd5b5060095461058d9061010090046001600160a01b031681565b3480156107fd57600080fd5b506102d561080c366004612e14565b611e7e565b61082461081f366004613147565b6120b1565b60405161028d9291906131e2565b34801561083e57600080fd5b506102d561084d366004612e66565b61225f565b34801561085e57600080fd5b506102d561086d36600461327c565b612284565b34801561087e57600080fd5b506102d561088d36600461329e565b6122b9565b60006001600160e01b03198216637965db0b60e01b14806108c357506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006108d48461133f565b600085815260056020908152604080832033845290915290208151919250906109279064e8d4a51000906109129087906001600160801b0316612468565b61091c91906132fc565b6001830154906124d8565b60018201558054610938908561256c565b81556004805460009190879081106109525761095261331e565b6000918252602090912001546001600160a01b0316905080156109d85781546040516345fb1ba160e11b81526001600160a01b03831691638bf63742916109a5918a9133918a9160009190600401613334565b600060405180830381600087803b1580156109bf57600080fd5b505af11580156109d3573d6000803e3d6000fd5b505050505b610a0c8486600389815481106109f0576109f061331e565b6000918252602090912001546001600160a01b031691906125c2565b836001600160a01b031686336001600160a01b03167f8166bf25f8a2b7ed3c85049207da4358d16edbed977d23fa2ee6f0dde3ec213288604051610a5291815260200190565b60405180910390a4505050505050565b60028181548110610a7257600080fd5b6000918252602090912060029091020180546001909101546001600160801b03821692506001600160401b03600160801b8304811692600160c01b9004169084565b6000610abf8361133f565b6000848152600560209081526040808320338452909152812082518154939450909264e8d4a5100091610afb91906001600160801b0316612468565b610b0591906132fc565b90506000610b28610b238460010154846124d890919063ffffffff16565b6126dd565b6001840183905590508015610b6b57610b6b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001686836125c2565b600060048781548110610b8057610b8061331e565b6000918252602090912001546001600160a01b031690508015610c055783546040516345fb1ba160e11b81526001600160a01b03831691638bf6374291610bd2918b9133918c91899190600401613334565b600060405180830381600087803b158015610bec57600080fd5b505af1158015610c00573d6000803e3d6000fd5b505050505b604051828152879033907f71bab65ced2e5750775a0613be067df48ef06cf92a496ebf7663ae06609249549060200160405180910390a350505050505050565b610c4d612721565b600855565b60008060028481548110610c6857610c6861331e565b6000918252602080832060408051608081018252600290940290910180546001600160801b0380821686526001600160401b03600160801b8304811687870152600160c01b909204909116858401526001909101546060850152888552600583528185206001600160a01b03891686529092528320825160038054949650919492169288908110610cfb57610cfb61331e565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d709190613363565b905083602001516001600160401b031642118015610d8d57508015155b15610e1c576000610db485602001516001600160401b03164261256c90919063ffffffff16565b90506000600654610de787604001516001600160401b0316610de16007548661246890919063ffffffff16565b90612468565b610df191906132fc565b9050610e1783610e068364e8d4a51000612468565b610e1091906132fc565b8590612755565b935050505b60018301548354610e4c91610b239164e8d4a5100090610e3c9087612468565b610e4691906132fc565b906124d8565b979650505050505050565b610e5f612721565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600082815260208190526040902060010154610e9c816127ae565b610ea683836127bb565b505050565b60008281526005602090815260408083203384529091528120805482825560018201839055600480549293919286908110610ee857610ee861331e565b6000918252602090912001546001600160a01b031690508015610f6d576040516345fb1ba160e11b81526001600160a01b03821690638bf6374290610f3a908890339089906000908190600401613334565b600060405180830381600087803b158015610f5457600080fd5b505af1158015610f68573d6000803e3d6000fd5b505050505b610f858483600388815481106109f0576109f061331e565b836001600160a01b031685336001600160a01b03167f2cac5e20e1541d836381527a43f651851e302817b71dc8e810284e69210c1c6b85604051610fcb91815260200190565b60405180910390a45050505050565b6001600160a01b038116331461104f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b611059828261283f565b5050565b6001546001600160a01b03166110b55760405162461bcd60e51b815260206004820152601d60248201527f4d61737465724368656656323a206e6f206d69677261746f72207365740000006044820152606401611046565b6000600382815481106110ca576110ca61331e565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa15801561111d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111419190613363565b60015460405163095ea7b360e01b81526001600160a01b0391821660048201526024810183905291925083169063095ea7b3906044016020604051808303816000875af1158015611196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ba919061337c565b5060015460405163ce5494bb60e01b81526001600160a01b038481166004830152600092169063ce5494bb906024016020604051808303816000875af1158015611208573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122c9190613399565b6040516370a0823160e01b81523060048201529091506001600160a01b038216906370a0823190602401602060405180830381865afa158015611273573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112979190613363565b82146112f75760405162461bcd60e51b815260206004820152602960248201527f4d61737465724368656656323a206d696772617465642062616c616e6365206d6044820152680eae6e840dac2e8c6d60bb1b6064820152608401611046565b806003858154811061130b5761130b61331e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050505050565b604080516080810182526000808252602082018190529181018290526060810191909152600282815481106113765761137661331e565b600091825260209182902060408051608081018252600290930290910180546001600160801b03811684526001600160401b03600160801b8204811695850195909552600160c01b900490931690820152600190910154606082015260085490915042106113e8576113e86000611dbf565b80602001516001600160401b031642111561161a576000600383815481106114125761141261331e565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611463573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114879190613363565b9050801561152e5760006114b183602001516001600160401b03164261256c90919063ffffffff16565b905060006006546114de85604001516001600160401b0316610de16007548661246890919063ffffffff16565b6114e891906132fc565b905061152061150f846115008464e8d4a51000612468565b61150a91906132fc565b6128a4565b85516001600160801b0316906128fd565b6001600160801b0316845250505b61153742612968565b6001600160401b03166020830152600280548391908590811061155c5761155c61331e565b60009182526020918290208351600292909202018054848401516040808701516001600160401b03908116600160c01b026001600160c01b03938216600160801b026001600160c01b03199095166001600160801b0397881617949094179290921692909217835560609586015160019093019290925586840151875182519190931681529384018690529116828201525185927f0fc9545022a542541ad085d091fb09a2ab36fee366a4576ab63714ea907ad353928290030190a2505b919050565b8060005b8181101561165d5761164c8484838181106116405761164061331e565b9050602002013561133f565b50611656816133b6565b9050611623565b50505050565b61166b612721565b6116806723a7ab22a92727a960c11b3361283f565b6116956723a7ab22a92727a960c11b826127bb565b604080513381526001600160a01b03831660208201527f5af6a85e864342d4f108c43dd574d98480c91f1de0ac2a9f66d826dee49bd9bb91015b60405180910390a150565b600381815481106116ea57600080fd5b6000918252602090912001546001600160a01b0316905081565b60405163d505accf60e01b81526001600160a01b0388811660048301528781166024830152604482018790526064820186905260ff8516608483015260a4820184905260c4820183905289169063d505accf9060e401600060405180830381600087803b15801561177457600080fd5b505af1158015611788573d6000803e3d6000fd5b505050505050505050505050565b6117ab6723a7ab22a92727a960c11b33611d40565b806117c657506117c66727a822a920aa27a960c11b33611d40565b6117e35760405163b8762e7760e01b815260040160405180910390fd5b61182d83611827600287815481106117fd576117fd61331e565b600091825260209091206002909102015460065490600160c01b90046001600160401b031661256c565b90612755565b60065561183983612968565b6002858154811061184c5761184c61331e565b906000526020600020906002020160000160186101000a8154816001600160401b0302191690836001600160401b0316021790555080156118ca57816004858154811061189b5761189b61331e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b806118fc57600484815481106118e2576118e261331e565b6000918252602090912001546001600160a01b03166118fe565b815b6001600160a01b0316847f95895a6ab1df54420d241b55243258a33e61b2194db66c1179ec521aae8e186585846040516119449291909182521515602082015260400190565b60405180910390a350505050565b600061195d8461133f565b60008581526005602090815260408083206001600160a01b038716845290915281206009549293509160ff1680156119985750606083015115155b80156119b3575060095461010090046001600160a01b031615155b15611a2c5764e8d4a510006119d584606001518761246890919063ffffffff16565b6119df91906132fc565b9050611a2c33600960019054906101000a90046001600160a01b03168360038a81548110611a0f57611a0f61331e565b6000918252602090912001546001600160a01b03169291906129c1565b611a3681866133cf565b8254909550611a459086612755565b82558251611a7d9064e8d4a5100090611a689088906001600160801b0316612468565b611a7291906132fc565b600184015490612ae5565b8260010181905550600060048781548110611a9a57611a9a61331e565b6000918252602090912001546001600160a01b031690508015611b205782546040516345fb1ba160e11b81526001600160a01b03831691638bf6374291611aed918b918a91829160009190600401613334565b600060405180830381600087803b158015611b0757600080fd5b505af1158015611b1b573d6000803e3d6000fd5b505050505b611b3933308860038b81548110611a0f57611a0f61331e565b60408051878152602081018490526001600160a01b03871691899133917eab9ea1934a18c419ebd648dfd54350d24ab746230b97428774bd8d923f4eaf910160405180910390a450505050505050565b611b91612721565b815160005b81811015611c5e576000848281518110611bb257611bb261331e565b60209081029190910101516040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611c07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2b9190613363565b90508015611c4757611c476001600160a01b03831688836125c2565b505060010180611c56816133b6565b915050611b96565b5047828015611c6d5750600081115b15611ce8576000856001600160a01b03168260405160006040518083038185875af1925050503d8060008114611cbf576040519150601f19603f3d011682016040523d82523d6000602084013e611cc4565b606091505b5050905080611ce65760405163505e179b60e11b815260040160405180910390fd5b505b6001600160a01b038516337f7dc5f7b59ca8f56b6fc2b00d2a5c9773cdadfc072a508b0ffae09949da8255ec8686611d21576000611d23565b845b604051611d319291906133e2565b60405180910390a35050505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b611d71612721565b611d866727a822a920aa27a960c11b826127bb565b6040516001600160a01b03821681527fac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d906020016116cf565b611dc7612721565b60078190556040518181527fc6ce5eff3291fb2c1517b943daa5067ea76c83816bbf674307fbc7fea3b311d0906020016116cf565b611e04612721565b6009805460ff19811660ff90911615179055565b611e20612721565b611e356727a822a920aa27a960c11b8261283f565b6040516001600160a01b03821681527f80c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d906020016116cf565b600481815481106116ea57600080fd5b6000611e898461133f565b6000858152600560209081526040808320338452909152812082518154939450909264e8d4a5100091611ec591906001600160801b0316612468565b611ecf91906132fc565b90506000611eed610b238460010154846124d890919063ffffffff16565b9050611f2964e8d4a51000611f1886600001516001600160801b03168961246890919063ffffffff16565b611f2291906132fc565b83906124d8565b60018401558254611f3a908761256c565b8355611f706001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001686836125c2565b600060048881548110611f8557611f8561331e565b6000918252602090912001546001600160a01b03169050801561200a5783546040516345fb1ba160e11b81526001600160a01b03831691638bf6374291611fd7918c9133918c91899190600401613334565b600060405180830381600087803b158015611ff157600080fd5b505af1158015612005573d6000803e3d6000fd5b505050505b612022868860038b815481106109f0576109f061331e565b856001600160a01b031688336001600160a01b03167f8166bf25f8a2b7ed3c85049207da4358d16edbed977d23fa2ee6f0dde3ec21328a60405161206891815260200190565b60405180910390a4604051828152889033907f71bab65ced2e5750775a0613be067df48ef06cf92a496ebf7663ae06609249549060200160405180910390a35050505050505050565b606080836001600160401b038111156120cc576120cc61302b565b6040519080825280602002602001820160405280156120f5578160200160208202803683370190505b509150836001600160401b038111156121105761211061302b565b60405190808252806020026020018201604052801561214357816020015b606081526020019060019003908161212e5790505b50905060005b8481101561225657600080308888858181106121675761216761331e565b90506020028101906121799190613433565b604051612187929190613479565b600060405180830381855af49150503d80600081146121c2576040519150601f19603f3d011682016040523d82523d6000602084013e6121c7565b606091505b509150915081806121d6575085155b6121df82612b70565b906121fd5760405162461bcd60e51b81526004016110469190613489565b50818584815181106122115761221161331e565b602002602001019015159081151581525050808484815181106122365761223661331e565b60200260200101819052505050808061224e906133b6565b915050612149565b50935093915050565b60008281526020819052604090206001015461227a816127ae565b610ea6838361283f565b61228c612721565b80600283815481106122a0576122a061331e565b9060005260206000209060020201600101819055505050565b6122c1612721565b6006546122ce9085612755565b6006556003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b038087166001600160a01b03199283161790925560048054938401815560009081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b90930180549286169290911691909117905560408051608081019091529081526002906020810161237b42612968565b6001600160401b0316815260200161239287612968565b6001600160401b0390811682526020918201859052835460018181018655600095865294839020845160029092020180549385015160408601518416600160c01b026001600160c01b0391909416600160801b026001600160c01b03199095166001600160801b03909316929092179390931716178155606090910151908201556003546001600160a01b03808516929086169161242f9161256c565b6040518781527f81ee0f8c5c46e2cb41984886f77a84181724abb86c32a5f6de539b07509d45e59060200160405180910390a450505050565b600081158061248c5750828261247e818361349c565b925061248a90836132fc565b145b6108c35760405162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a204d756c204f766572666c6f7700000000000000006044820152606401611046565b6000806124e583856134b3565b9050600083121580156124f85750838113155b8061250d575060008312801561250d57508381135b6125655760405162461bcd60e51b8152602060048201526024808201527f5369676e6564536166654d6174683a207375627472616374696f6e206f766572604482015263666c6f7760e01b6064820152608401611046565b9392505050565b60008261257983826133cf565b91508111156108c35760405162461bcd60e51b8152602060048201526015602482015274426f72696e674d6174683a20556e646572666c6f7760581b6044820152606401611046565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161261e91906134da565b6000604051808303816000865af19150503d806000811461265b576040519150601f19603f3d011682016040523d82523d6000602084013e612660565b606091505b509150915081801561268a57508051158061268a57508080602001905181019061268a919061337c565b6126d65760405162461bcd60e51b815260206004820152601c60248201527f426f72696e6745524332303a205472616e73666572206661696c6564000000006044820152606401611046565b5050505050565b60008082121561271d5760405162461bcd60e51b815260206004820152600b60248201526a0496e7465676572203c20360ac1b6044820152606401611046565b5090565b6127366723a7ab22a92727a960c11b33611d40565b612753576040516303fa15f960e11b815260040160405180910390fd5b565b60008161276281856134f6565b91508110156108c35760405162461bcd60e51b8152602060048201526018602482015277426f72696e674d6174683a20416464204f766572666c6f7760401b6044820152606401611046565b6127b88133612bcf565b50565b6127c58282611d40565b611059576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556127fb3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6128498282611d40565b15611059576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006001600160801b0382111561271d5760405162461bcd60e51b815260206004820152601c60248201527f426f72696e674d6174683a2075696e74313238204f766572666c6f77000000006044820152606401611046565b60006001600160801b0382166129138385613509565b9150816001600160801b031610156108c35760405162461bcd60e51b8152602060048201526018602482015277426f72696e674d6174683a20416464204f766572666c6f7760401b6044820152606401611046565b60006001600160401b0382111561271d5760405162461bcd60e51b815260206004820152601b60248201527f426f72696e674d6174683a2075696e743634204f766572666c6f7700000000006044820152606401611046565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612a2591906134da565b6000604051808303816000865af19150503d8060008114612a62576040519150601f19603f3d011682016040523d82523d6000602084013e612a67565b606091505b5091509150818015612a91575080511580612a91575080806020019051810190612a91919061337c565b612add5760405162461bcd60e51b815260206004820181905260248201527f426f72696e6745524332303a205472616e7366657246726f6d206661696c65646044820152606401611046565b505050505050565b600080612af28385613529565b905060008312158015612b055750838112155b80612b1a5750600083128015612b1a57508381125b6125655760405162461bcd60e51b815260206004820152602160248201527f5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f6044820152607760f81b6064820152608401611046565b6060604482511015612bb557505060408051808201909152601d81527f5472616e73616374696f6e2072657665727465642073696c656e746c79000000602082015290565b600482019150818060200190518101906108c39190613551565b612bd98282611d40565b61105957612be681612c28565b612bf1836020612c3a565b604051602001612c029291906135e4565b60408051601f198184030181529082905262461bcd60e51b825261104691600401613489565b60606108c36001600160a01b03831660145b60606000612c4983600261349c565b612c549060026134f6565b6001600160401b03811115612c6b57612c6b61302b565b6040519080825280601f01601f191660200182016040528015612c95576020820181803683370190505b509050600360fc1b81600081518110612cb057612cb061331e565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612cdf57612cdf61331e565b60200101906001600160f81b031916908160001a9053506000612d0384600261349c565b612d0e9060016134f6565b90505b6001811115612d86576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612d4257612d4261331e565b1a60f81b828281518110612d5857612d5861331e565b60200101906001600160f81b031916908160001a90535060049490941c93612d7f81613659565b9050612d11565b5083156125655760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401611046565b600060208284031215612de757600080fd5b81356001600160e01b03198116811461256557600080fd5b6001600160a01b03811681146127b857600080fd5b600080600060608486031215612e2957600080fd5b83359250602084013591506040840135612e4281612dff565b809150509250925092565b600060208284031215612e5f57600080fd5b5035919050565b60008060408385031215612e7957600080fd5b823591506020830135612e8b81612dff565b809150509250929050565b600060208284031215612ea857600080fd5b813561256581612dff565b60008083601f840112612ec557600080fd5b5081356001600160401b03811115612edc57600080fd5b6020830191508360208260051b8501011115612ef757600080fd5b9250929050565b60008060208385031215612f1157600080fd5b82356001600160401b03811115612f2757600080fd5b612f3385828601612eb3565b90969095509350505050565b600080600080600080600080610100898b031215612f5c57600080fd5b8835612f6781612dff565b97506020890135612f7781612dff565b96506040890135612f8781612dff565b9550606089013594506080890135935060a089013560ff81168114612fab57600080fd5b979a969950949793969295929450505060c08201359160e0013590565b80151581146127b857600080fd5b803561161a81612fc8565b60008060008060808587031215612ff757600080fd5b8435935060208501359250604085013561301081612dff565b9150606085013561302081612fc8565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156130695761306961302b565b604052919050565b60008060006060848603121561308657600080fd5b833561309181612dff565b92506020848101356001600160401b03808211156130ae57600080fd5b818701915087601f8301126130c257600080fd5b8135818111156130d4576130d461302b565b8060051b91506130e5848301613041565b818152918301840191848101908a8411156130ff57600080fd5b938501935b83851015613129578435925061311983612dff565b8282529385019390850190613104565b80975050505050505061313e60408501612fd6565b90509250925092565b60008060006040848603121561315c57600080fd5b83356001600160401b0381111561317257600080fd5b61317e86828701612eb3565b9094509250506020840135612e4281612fc8565b60005b838110156131ad578181015183820152602001613195565b50506000910152565b600081518084526131ce816020860160208601613192565b601f01601f19169290920160200192915050565b604080825283519082018190526000906020906060840190828701845b8281101561321d5781511515845292840192908401906001016131ff565b50505083810382850152845180825282820190600581901b8301840187850160005b8381101561326d57601f1986840301855261325b8383516131b6565b9487019492509086019060010161323f565b50909998505050505050505050565b6000806040838503121561328f57600080fd5b50508035926020909101359150565b600080600080608085870312156132b457600080fd5b8435935060208501356132c681612dff565b925060408501356132d681612dff565b9396929550929360600135925050565b634e487b7160e01b600052601160045260246000fd5b60008261331957634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b9485526001600160a01b0393841660208601529190921660408401526060830191909152608082015260a00190565b60006020828403121561337557600080fd5b5051919050565b60006020828403121561338e57600080fd5b815161256581612fc8565b6000602082840312156133ab57600080fd5b815161256581612dff565b6000600182016133c8576133c86132e6565b5060010190565b818103818111156108c3576108c36132e6565b604080825283519082018190526000906020906060840190828701845b828110156134245781516001600160a01b0316845292840192908401906001016133ff565b50505092019290925292915050565b6000808335601e1984360301811261344a57600080fd5b8301803591506001600160401b0382111561346457600080fd5b602001915036819003821315612ef757600080fd5b8183823760009101908152919050565b60208152600061256560208301846131b6565b80820281158282048414176108c3576108c36132e6565b81810360008312801583831316838312821617156134d3576134d36132e6565b5092915050565b600082516134ec818460208701613192565b9190910192915050565b808201808211156108c3576108c36132e6565b6001600160801b038181168382160190808211156134d3576134d36132e6565b8082018281126000831280158216821582161715613549576135496132e6565b505092915050565b60006020828403121561356357600080fd5b81516001600160401b038082111561357a57600080fd5b818401915084601f83011261358e57600080fd5b8151818111156135a0576135a061302b565b6135b3601f8201601f1916602001613041565b91508082528560208285010111156135ca57600080fd5b6135db816020840160208601613192565b50949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161361c816017850160208801613192565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161364d816028840160208801613192565b01602801949350505050565b600081613668576136686132e6565b50600019019056fea2646970667358221220310c509e902844052a049211e8ad3a7a40a21100fda4342712a17f963819461364736f6c63430008140033000000000000000000000000912ce59144191c1204e64559fe8253a0e49e65480000000000000000000000005a446ba4d4bf482a3e63648e76e9404e784f7bbc
Deployed Bytecode
0x60806040526004361061025c5760003560e01c80637c516e9411610144578063a217fddf116100b6578063c4ade30b1161007a578063c4ade30b146107cc578063d1abb907146107f1578063d2423b5114610811578063d547741f14610832578063d8e96c2314610852578063f9aee4601461087257600080fd5b8063a217fddf1461072e578063a5a362d614610743578063ab560e1014610758578063ac8a584a1461078c578063c346253d146107ac57600080fd5b806391d148541161010857806391d148541461064557806393f1a40b14610665578063983d2737146106b95780639870d7fe146106d85780639baf58c3146106f8578063a06e408b1461071857600080fd5b80637c516e94146105a55780637cd07e47146105c557806388bba42f146105e55780638dbdbe6d146106055780639195ebc61461062557600080fd5b806329dcb0cf116101dd57806351eb05a6116101a157806351eb05a61461048a57806357a5b58c146104f457806362f384ad146105145780636cdfa1b7146105345780636dc0ae221461054e57806378ed5d1f1461056d57600080fd5b806329dcb0cf146103f45780632f2ff15d1461040a5780632f940c701461042a57806336568abe1461044a578063454b06081461046a57600080fd5b806318fccc761161022457806318fccc7614610344578063195199f614610364578063195426ec1461038457806323cf3118146103a4578063248a9ca3146103c457600080fd5b806301ffc9a714610261578063081e3eda146102965780630ad58d2f146102b55780631526fe27146102d757806317caf6f11461032e575b600080fd5b34801561026d57600080fd5b5061028161027c366004612dd5565b610892565b60405190151581526020015b60405180910390f35b3480156102a257600080fd5b506002545b60405190815260200161028d565b3480156102c157600080fd5b506102d56102d0366004612e14565b6108c9565b005b3480156102e357600080fd5b506102f76102f2366004612e4d565b610a62565b604080516001600160801b039590951685526001600160401b0393841660208601529190921690830152606082015260800161028d565b34801561033a57600080fd5b506102a760065481565b34801561035057600080fd5b506102d561035f366004612e66565b610ab4565b34801561037057600080fd5b506102d561037f366004612e4d565b610c45565b34801561039057600080fd5b506102a761039f366004612e66565b610c52565b3480156103b057600080fd5b506102d56103bf366004612e96565b610e57565b3480156103d057600080fd5b506102a76103df366004612e4d565b60009081526020819052604090206001015490565b34801561040057600080fd5b506102a760085481565b34801561041657600080fd5b506102d5610425366004612e66565b610e81565b34801561043657600080fd5b506102d5610445366004612e66565b610eab565b34801561045657600080fd5b506102d5610465366004612e66565b610fda565b34801561047657600080fd5b506102d5610485366004612e4d565b61105d565b34801561049657600080fd5b506104aa6104a5366004612e4d565b61133f565b6040805182516001600160801b031681526020808401516001600160401b03908116918301919091528383015116918101919091526060918201519181019190915260800161028d565b34801561050057600080fd5b506102d561050f366004612efe565b61161f565b34801561052057600080fd5b506102d561052f366004612e96565b611663565b34801561054057600080fd5b506009546102819060ff1681565b34801561055a57600080fd5b506102a76723a7ab22a92727a960c11b81565b34801561057957600080fd5b5061058d610588366004612e4d565b6116da565b6040516001600160a01b03909116815260200161028d565b3480156105b157600080fd5b506102d56105c0366004612f3f565b611704565b3480156105d157600080fd5b5060015461058d906001600160a01b031681565b3480156105f157600080fd5b506102d5610600366004612fe1565b611796565b34801561061157600080fd5b506102d5610620366004612e14565b611952565b34801561063157600080fd5b506102d5610640366004613071565b611b89565b34801561065157600080fd5b50610281610660366004612e66565b611d40565b34801561067157600080fd5b506106a4610680366004612e66565b60056020908152600092835260408084209091529082529020805460019091015482565b6040805192835260208301919091520161028d565b3480156106c557600080fd5b506102a76727a822a920aa27a960c11b81565b3480156106e457600080fd5b506102d56106f3366004612e96565b611d69565b34801561070457600080fd5b506102d5610713366004612e4d565b611dbf565b34801561072457600080fd5b506102a760075481565b34801561073a57600080fd5b506102a7600081565b34801561074f57600080fd5b506102d5611dfc565b34801561076457600080fd5b5061058d7f000000000000000000000000912ce59144191c1204e64559fe8253a0e49e654881565b34801561079857600080fd5b506102d56107a7366004612e96565b611e18565b3480156107b857600080fd5b5061058d6107c7366004612e4d565b611e6e565b3480156107d857600080fd5b5060095461058d9061010090046001600160a01b031681565b3480156107fd57600080fd5b506102d561080c366004612e14565b611e7e565b61082461081f366004613147565b6120b1565b60405161028d9291906131e2565b34801561083e57600080fd5b506102d561084d366004612e66565b61225f565b34801561085e57600080fd5b506102d561086d36600461327c565b612284565b34801561087e57600080fd5b506102d561088d36600461329e565b6122b9565b60006001600160e01b03198216637965db0b60e01b14806108c357506301ffc9a760e01b6001600160e01b03198316145b92915050565b60006108d48461133f565b600085815260056020908152604080832033845290915290208151919250906109279064e8d4a51000906109129087906001600160801b0316612468565b61091c91906132fc565b6001830154906124d8565b60018201558054610938908561256c565b81556004805460009190879081106109525761095261331e565b6000918252602090912001546001600160a01b0316905080156109d85781546040516345fb1ba160e11b81526001600160a01b03831691638bf63742916109a5918a9133918a9160009190600401613334565b600060405180830381600087803b1580156109bf57600080fd5b505af11580156109d3573d6000803e3d6000fd5b505050505b610a0c8486600389815481106109f0576109f061331e565b6000918252602090912001546001600160a01b031691906125c2565b836001600160a01b031686336001600160a01b03167f8166bf25f8a2b7ed3c85049207da4358d16edbed977d23fa2ee6f0dde3ec213288604051610a5291815260200190565b60405180910390a4505050505050565b60028181548110610a7257600080fd5b6000918252602090912060029091020180546001909101546001600160801b03821692506001600160401b03600160801b8304811692600160c01b9004169084565b6000610abf8361133f565b6000848152600560209081526040808320338452909152812082518154939450909264e8d4a5100091610afb91906001600160801b0316612468565b610b0591906132fc565b90506000610b28610b238460010154846124d890919063ffffffff16565b6126dd565b6001840183905590508015610b6b57610b6b6001600160a01b037f000000000000000000000000912ce59144191c1204e64559fe8253a0e49e65481686836125c2565b600060048781548110610b8057610b8061331e565b6000918252602090912001546001600160a01b031690508015610c055783546040516345fb1ba160e11b81526001600160a01b03831691638bf6374291610bd2918b9133918c91899190600401613334565b600060405180830381600087803b158015610bec57600080fd5b505af1158015610c00573d6000803e3d6000fd5b505050505b604051828152879033907f71bab65ced2e5750775a0613be067df48ef06cf92a496ebf7663ae06609249549060200160405180910390a350505050505050565b610c4d612721565b600855565b60008060028481548110610c6857610c6861331e565b6000918252602080832060408051608081018252600290940290910180546001600160801b0380821686526001600160401b03600160801b8304811687870152600160c01b909204909116858401526001909101546060850152888552600583528185206001600160a01b03891686529092528320825160038054949650919492169288908110610cfb57610cfb61331e565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015610d4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d709190613363565b905083602001516001600160401b031642118015610d8d57508015155b15610e1c576000610db485602001516001600160401b03164261256c90919063ffffffff16565b90506000600654610de787604001516001600160401b0316610de16007548661246890919063ffffffff16565b90612468565b610df191906132fc565b9050610e1783610e068364e8d4a51000612468565b610e1091906132fc565b8590612755565b935050505b60018301548354610e4c91610b239164e8d4a5100090610e3c9087612468565b610e4691906132fc565b906124d8565b979650505050505050565b610e5f612721565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b600082815260208190526040902060010154610e9c816127ae565b610ea683836127bb565b505050565b60008281526005602090815260408083203384529091528120805482825560018201839055600480549293919286908110610ee857610ee861331e565b6000918252602090912001546001600160a01b031690508015610f6d576040516345fb1ba160e11b81526001600160a01b03821690638bf6374290610f3a908890339089906000908190600401613334565b600060405180830381600087803b158015610f5457600080fd5b505af1158015610f68573d6000803e3d6000fd5b505050505b610f858483600388815481106109f0576109f061331e565b836001600160a01b031685336001600160a01b03167f2cac5e20e1541d836381527a43f651851e302817b71dc8e810284e69210c1c6b85604051610fcb91815260200190565b60405180910390a45050505050565b6001600160a01b038116331461104f5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084015b60405180910390fd5b611059828261283f565b5050565b6001546001600160a01b03166110b55760405162461bcd60e51b815260206004820152601d60248201527f4d61737465724368656656323a206e6f206d69677261746f72207365740000006044820152606401611046565b6000600382815481106110ca576110ca61331e565b60009182526020822001546040516370a0823160e01b81523060048201526001600160a01b03909116925082906370a0823190602401602060405180830381865afa15801561111d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111419190613363565b60015460405163095ea7b360e01b81526001600160a01b0391821660048201526024810183905291925083169063095ea7b3906044016020604051808303816000875af1158015611196573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ba919061337c565b5060015460405163ce5494bb60e01b81526001600160a01b038481166004830152600092169063ce5494bb906024016020604051808303816000875af1158015611208573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122c9190613399565b6040516370a0823160e01b81523060048201529091506001600160a01b038216906370a0823190602401602060405180830381865afa158015611273573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112979190613363565b82146112f75760405162461bcd60e51b815260206004820152602960248201527f4d61737465724368656656323a206d696772617465642062616c616e6365206d6044820152680eae6e840dac2e8c6d60bb1b6064820152608401611046565b806003858154811061130b5761130b61331e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050505050565b604080516080810182526000808252602082018190529181018290526060810191909152600282815481106113765761137661331e565b600091825260209182902060408051608081018252600290930290910180546001600160801b03811684526001600160401b03600160801b8204811695850195909552600160c01b900490931690820152600190910154606082015260085490915042106113e8576113e86000611dbf565b80602001516001600160401b031642111561161a576000600383815481106114125761141261331e565b6000918252602090912001546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611463573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114879190613363565b9050801561152e5760006114b183602001516001600160401b03164261256c90919063ffffffff16565b905060006006546114de85604001516001600160401b0316610de16007548661246890919063ffffffff16565b6114e891906132fc565b905061152061150f846115008464e8d4a51000612468565b61150a91906132fc565b6128a4565b85516001600160801b0316906128fd565b6001600160801b0316845250505b61153742612968565b6001600160401b03166020830152600280548391908590811061155c5761155c61331e565b60009182526020918290208351600292909202018054848401516040808701516001600160401b03908116600160c01b026001600160c01b03938216600160801b026001600160c01b03199095166001600160801b0397881617949094179290921692909217835560609586015160019093019290925586840151875182519190931681529384018690529116828201525185927f0fc9545022a542541ad085d091fb09a2ab36fee366a4576ab63714ea907ad353928290030190a2505b919050565b8060005b8181101561165d5761164c8484838181106116405761164061331e565b9050602002013561133f565b50611656816133b6565b9050611623565b50505050565b61166b612721565b6116806723a7ab22a92727a960c11b3361283f565b6116956723a7ab22a92727a960c11b826127bb565b604080513381526001600160a01b03831660208201527f5af6a85e864342d4f108c43dd574d98480c91f1de0ac2a9f66d826dee49bd9bb91015b60405180910390a150565b600381815481106116ea57600080fd5b6000918252602090912001546001600160a01b0316905081565b60405163d505accf60e01b81526001600160a01b0388811660048301528781166024830152604482018790526064820186905260ff8516608483015260a4820184905260c4820183905289169063d505accf9060e401600060405180830381600087803b15801561177457600080fd5b505af1158015611788573d6000803e3d6000fd5b505050505050505050505050565b6117ab6723a7ab22a92727a960c11b33611d40565b806117c657506117c66727a822a920aa27a960c11b33611d40565b6117e35760405163b8762e7760e01b815260040160405180910390fd5b61182d83611827600287815481106117fd576117fd61331e565b600091825260209091206002909102015460065490600160c01b90046001600160401b031661256c565b90612755565b60065561183983612968565b6002858154811061184c5761184c61331e565b906000526020600020906002020160000160186101000a8154816001600160401b0302191690836001600160401b0316021790555080156118ca57816004858154811061189b5761189b61331e565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505b806118fc57600484815481106118e2576118e261331e565b6000918252602090912001546001600160a01b03166118fe565b815b6001600160a01b0316847f95895a6ab1df54420d241b55243258a33e61b2194db66c1179ec521aae8e186585846040516119449291909182521515602082015260400190565b60405180910390a350505050565b600061195d8461133f565b60008581526005602090815260408083206001600160a01b038716845290915281206009549293509160ff1680156119985750606083015115155b80156119b3575060095461010090046001600160a01b031615155b15611a2c5764e8d4a510006119d584606001518761246890919063ffffffff16565b6119df91906132fc565b9050611a2c33600960019054906101000a90046001600160a01b03168360038a81548110611a0f57611a0f61331e565b6000918252602090912001546001600160a01b03169291906129c1565b611a3681866133cf565b8254909550611a459086612755565b82558251611a7d9064e8d4a5100090611a689088906001600160801b0316612468565b611a7291906132fc565b600184015490612ae5565b8260010181905550600060048781548110611a9a57611a9a61331e565b6000918252602090912001546001600160a01b031690508015611b205782546040516345fb1ba160e11b81526001600160a01b03831691638bf6374291611aed918b918a91829160009190600401613334565b600060405180830381600087803b158015611b0757600080fd5b505af1158015611b1b573d6000803e3d6000fd5b505050505b611b3933308860038b81548110611a0f57611a0f61331e565b60408051878152602081018490526001600160a01b03871691899133917eab9ea1934a18c419ebd648dfd54350d24ab746230b97428774bd8d923f4eaf910160405180910390a450505050505050565b611b91612721565b815160005b81811015611c5e576000848281518110611bb257611bb261331e565b60209081029190910101516040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611c07573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c2b9190613363565b90508015611c4757611c476001600160a01b03831688836125c2565b505060010180611c56816133b6565b915050611b96565b5047828015611c6d5750600081115b15611ce8576000856001600160a01b03168260405160006040518083038185875af1925050503d8060008114611cbf576040519150601f19603f3d011682016040523d82523d6000602084013e611cc4565b606091505b5050905080611ce65760405163505e179b60e11b815260040160405180910390fd5b505b6001600160a01b038516337f7dc5f7b59ca8f56b6fc2b00d2a5c9773cdadfc072a508b0ffae09949da8255ec8686611d21576000611d23565b845b604051611d319291906133e2565b60405180910390a35050505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b611d71612721565b611d866727a822a920aa27a960c11b826127bb565b6040516001600160a01b03821681527fac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d906020016116cf565b611dc7612721565b60078190556040518181527fc6ce5eff3291fb2c1517b943daa5067ea76c83816bbf674307fbc7fea3b311d0906020016116cf565b611e04612721565b6009805460ff19811660ff90911615179055565b611e20612721565b611e356727a822a920aa27a960c11b8261283f565b6040516001600160a01b03821681527f80c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d906020016116cf565b600481815481106116ea57600080fd5b6000611e898461133f565b6000858152600560209081526040808320338452909152812082518154939450909264e8d4a5100091611ec591906001600160801b0316612468565b611ecf91906132fc565b90506000611eed610b238460010154846124d890919063ffffffff16565b9050611f2964e8d4a51000611f1886600001516001600160801b03168961246890919063ffffffff16565b611f2291906132fc565b83906124d8565b60018401558254611f3a908761256c565b8355611f706001600160a01b037f000000000000000000000000912ce59144191c1204e64559fe8253a0e49e65481686836125c2565b600060048881548110611f8557611f8561331e565b6000918252602090912001546001600160a01b03169050801561200a5783546040516345fb1ba160e11b81526001600160a01b03831691638bf6374291611fd7918c9133918c91899190600401613334565b600060405180830381600087803b158015611ff157600080fd5b505af1158015612005573d6000803e3d6000fd5b505050505b612022868860038b815481106109f0576109f061331e565b856001600160a01b031688336001600160a01b03167f8166bf25f8a2b7ed3c85049207da4358d16edbed977d23fa2ee6f0dde3ec21328a60405161206891815260200190565b60405180910390a4604051828152889033907f71bab65ced2e5750775a0613be067df48ef06cf92a496ebf7663ae06609249549060200160405180910390a35050505050505050565b606080836001600160401b038111156120cc576120cc61302b565b6040519080825280602002602001820160405280156120f5578160200160208202803683370190505b509150836001600160401b038111156121105761211061302b565b60405190808252806020026020018201604052801561214357816020015b606081526020019060019003908161212e5790505b50905060005b8481101561225657600080308888858181106121675761216761331e565b90506020028101906121799190613433565b604051612187929190613479565b600060405180830381855af49150503d80600081146121c2576040519150601f19603f3d011682016040523d82523d6000602084013e6121c7565b606091505b509150915081806121d6575085155b6121df82612b70565b906121fd5760405162461bcd60e51b81526004016110469190613489565b50818584815181106122115761221161331e565b602002602001019015159081151581525050808484815181106122365761223661331e565b60200260200101819052505050808061224e906133b6565b915050612149565b50935093915050565b60008281526020819052604090206001015461227a816127ae565b610ea6838361283f565b61228c612721565b80600283815481106122a0576122a061331e565b9060005260206000209060020201600101819055505050565b6122c1612721565b6006546122ce9085612755565b6006556003805460018181019092557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b038087166001600160a01b03199283161790925560048054938401815560009081527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b90930180549286169290911691909117905560408051608081019091529081526002906020810161237b42612968565b6001600160401b0316815260200161239287612968565b6001600160401b0390811682526020918201859052835460018181018655600095865294839020845160029092020180549385015160408601518416600160c01b026001600160c01b0391909416600160801b026001600160c01b03199095166001600160801b03909316929092179390931716178155606090910151908201556003546001600160a01b03808516929086169161242f9161256c565b6040518781527f81ee0f8c5c46e2cb41984886f77a84181724abb86c32a5f6de539b07509d45e59060200160405180910390a450505050565b600081158061248c5750828261247e818361349c565b925061248a90836132fc565b145b6108c35760405162461bcd60e51b815260206004820152601860248201527f426f72696e674d6174683a204d756c204f766572666c6f7700000000000000006044820152606401611046565b6000806124e583856134b3565b9050600083121580156124f85750838113155b8061250d575060008312801561250d57508381135b6125655760405162461bcd60e51b8152602060048201526024808201527f5369676e6564536166654d6174683a207375627472616374696f6e206f766572604482015263666c6f7760e01b6064820152608401611046565b9392505050565b60008261257983826133cf565b91508111156108c35760405162461bcd60e51b8152602060048201526015602482015274426f72696e674d6174683a20556e646572666c6f7760581b6044820152606401611046565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161261e91906134da565b6000604051808303816000865af19150503d806000811461265b576040519150601f19603f3d011682016040523d82523d6000602084013e612660565b606091505b509150915081801561268a57508051158061268a57508080602001905181019061268a919061337c565b6126d65760405162461bcd60e51b815260206004820152601c60248201527f426f72696e6745524332303a205472616e73666572206661696c6564000000006044820152606401611046565b5050505050565b60008082121561271d5760405162461bcd60e51b815260206004820152600b60248201526a0496e7465676572203c20360ac1b6044820152606401611046565b5090565b6127366723a7ab22a92727a960c11b33611d40565b612753576040516303fa15f960e11b815260040160405180910390fd5b565b60008161276281856134f6565b91508110156108c35760405162461bcd60e51b8152602060048201526018602482015277426f72696e674d6174683a20416464204f766572666c6f7760401b6044820152606401611046565b6127b88133612bcf565b50565b6127c58282611d40565b611059576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556127fb3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6128498282611d40565b15611059576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006001600160801b0382111561271d5760405162461bcd60e51b815260206004820152601c60248201527f426f72696e674d6174683a2075696e74313238204f766572666c6f77000000006044820152606401611046565b60006001600160801b0382166129138385613509565b9150816001600160801b031610156108c35760405162461bcd60e51b8152602060048201526018602482015277426f72696e674d6174683a20416464204f766572666c6f7760401b6044820152606401611046565b60006001600160401b0382111561271d5760405162461bcd60e51b815260206004820152601b60248201527f426f72696e674d6174683a2075696e743634204f766572666c6f7700000000006044820152606401611046565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612a2591906134da565b6000604051808303816000865af19150503d8060008114612a62576040519150601f19603f3d011682016040523d82523d6000602084013e612a67565b606091505b5091509150818015612a91575080511580612a91575080806020019051810190612a91919061337c565b612add5760405162461bcd60e51b815260206004820181905260248201527f426f72696e6745524332303a205472616e7366657246726f6d206661696c65646044820152606401611046565b505050505050565b600080612af28385613529565b905060008312158015612b055750838112155b80612b1a5750600083128015612b1a57508381125b6125655760405162461bcd60e51b815260206004820152602160248201527f5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f6044820152607760f81b6064820152608401611046565b6060604482511015612bb557505060408051808201909152601d81527f5472616e73616374696f6e2072657665727465642073696c656e746c79000000602082015290565b600482019150818060200190518101906108c39190613551565b612bd98282611d40565b61105957612be681612c28565b612bf1836020612c3a565b604051602001612c029291906135e4565b60408051601f198184030181529082905262461bcd60e51b825261104691600401613489565b60606108c36001600160a01b03831660145b60606000612c4983600261349c565b612c549060026134f6565b6001600160401b03811115612c6b57612c6b61302b565b6040519080825280601f01601f191660200182016040528015612c95576020820181803683370190505b509050600360fc1b81600081518110612cb057612cb061331e565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612cdf57612cdf61331e565b60200101906001600160f81b031916908160001a9053506000612d0384600261349c565b612d0e9060016134f6565b90505b6001811115612d86576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612d4257612d4261331e565b1a60f81b828281518110612d5857612d5861331e565b60200101906001600160f81b031916908160001a90535060049490941c93612d7f81613659565b9050612d11565b5083156125655760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401611046565b600060208284031215612de757600080fd5b81356001600160e01b03198116811461256557600080fd5b6001600160a01b03811681146127b857600080fd5b600080600060608486031215612e2957600080fd5b83359250602084013591506040840135612e4281612dff565b809150509250925092565b600060208284031215612e5f57600080fd5b5035919050565b60008060408385031215612e7957600080fd5b823591506020830135612e8b81612dff565b809150509250929050565b600060208284031215612ea857600080fd5b813561256581612dff565b60008083601f840112612ec557600080fd5b5081356001600160401b03811115612edc57600080fd5b6020830191508360208260051b8501011115612ef757600080fd5b9250929050565b60008060208385031215612f1157600080fd5b82356001600160401b03811115612f2757600080fd5b612f3385828601612eb3565b90969095509350505050565b600080600080600080600080610100898b031215612f5c57600080fd5b8835612f6781612dff565b97506020890135612f7781612dff565b96506040890135612f8781612dff565b9550606089013594506080890135935060a089013560ff81168114612fab57600080fd5b979a969950949793969295929450505060c08201359160e0013590565b80151581146127b857600080fd5b803561161a81612fc8565b60008060008060808587031215612ff757600080fd5b8435935060208501359250604085013561301081612dff565b9150606085013561302081612fc8565b939692955090935050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156130695761306961302b565b604052919050565b60008060006060848603121561308657600080fd5b833561309181612dff565b92506020848101356001600160401b03808211156130ae57600080fd5b818701915087601f8301126130c257600080fd5b8135818111156130d4576130d461302b565b8060051b91506130e5848301613041565b818152918301840191848101908a8411156130ff57600080fd5b938501935b83851015613129578435925061311983612dff565b8282529385019390850190613104565b80975050505050505061313e60408501612fd6565b90509250925092565b60008060006040848603121561315c57600080fd5b83356001600160401b0381111561317257600080fd5b61317e86828701612eb3565b9094509250506020840135612e4281612fc8565b60005b838110156131ad578181015183820152602001613195565b50506000910152565b600081518084526131ce816020860160208601613192565b601f01601f19169290920160200192915050565b604080825283519082018190526000906020906060840190828701845b8281101561321d5781511515845292840192908401906001016131ff565b50505083810382850152845180825282820190600581901b8301840187850160005b8381101561326d57601f1986840301855261325b8383516131b6565b9487019492509086019060010161323f565b50909998505050505050505050565b6000806040838503121561328f57600080fd5b50508035926020909101359150565b600080600080608085870312156132b457600080fd5b8435935060208501356132c681612dff565b925060408501356132d681612dff565b9396929550929360600135925050565b634e487b7160e01b600052601160045260246000fd5b60008261331957634e487b7160e01b600052601260045260246000fd5b500490565b634e487b7160e01b600052603260045260246000fd5b9485526001600160a01b0393841660208601529190921660408401526060830191909152608082015260a00190565b60006020828403121561337557600080fd5b5051919050565b60006020828403121561338e57600080fd5b815161256581612fc8565b6000602082840312156133ab57600080fd5b815161256581612dff565b6000600182016133c8576133c86132e6565b5060010190565b818103818111156108c3576108c36132e6565b604080825283519082018190526000906020906060840190828701845b828110156134245781516001600160a01b0316845292840192908401906001016133ff565b50505092019290925292915050565b6000808335601e1984360301811261344a57600080fd5b8301803591506001600160401b0382111561346457600080fd5b602001915036819003821315612ef757600080fd5b8183823760009101908152919050565b60208152600061256560208301846131b6565b80820281158282048414176108c3576108c36132e6565b81810360008312801583831316838312821617156134d3576134d36132e6565b5092915050565b600082516134ec818460208701613192565b9190910192915050565b808201808211156108c3576108c36132e6565b6001600160801b038181168382160190808211156134d3576134d36132e6565b8082018281126000831280158216821582161715613549576135496132e6565b505092915050565b60006020828403121561356357600080fd5b81516001600160401b038082111561357a57600080fd5b818401915084601f83011261358e57600080fd5b8151818111156135a0576135a061302b565b6135b3601f8201601f1916602001613041565b91508082528560208285010111156135ca57600080fd5b6135db816020840160208601613192565b50949350505050565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161361c816017850160208801613192565b7001034b99036b4b9b9b4b733903937b6329607d1b601791840191820152835161364d816028840160208801613192565b01602801949350505050565b600081613668576136686132e6565b50600019019056fea2646970667358221220310c509e902844052a049211e8ad3a7a40a21100fda4342712a17f963819461364736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000912ce59144191c1204e64559fe8253a0e49e65480000000000000000000000005a446ba4d4bf482a3e63648e76e9404e784f7bbc
-----Decoded View---------------
Arg [0] : _sushi (address): 0x912CE59144191C1204E64559FE8253a0e49E6548
Arg [1] : _incentiveReceiver (address): 0x5A446ba4D4BF482a3E63648E76E9404E784f7BbC
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000912ce59144191c1204e64559fe8253a0e49e6548
Arg [1] : 0000000000000000000000005a446ba4d4bf482a3e63648e76e9404e784f7bbc
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$8,990.17
Net Worth in ETH
3.766701
Token Allocations
JUSDC
71.80%
ARB
20.36%
JGLP
7.84%
Multichain Portfolio | 35 Chains
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.