Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
Rewarder
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
//SPDX-License-Identifier: MIT pragma solidity >=0.6.11 <=0.6.12; interface IAddressRegistry { } contract BaseController { address public immutable manager; IAddressRegistry public immutable addressRegistry; constructor(address _manager, address _addressRegistry) public { require(_manager != address(0), "INVALID_ADDRESS"); require(_addressRegistry != address(0), "INVALID_ADDRESS"); manager = _manager; addressRegistry = IAddressRegistry(_addressRegistry); } modifier onlyManager() { require(msg.sender == manager, "NOT_MANAGER_ADDRESS"); _; } }
// Sources flattened with hardhat v2.0.11 https://hardhat.org // File @boringcrypto/boring-solidity/contracts/libraries/[email protected] // SPDX-License-Identifier: MIT pragma solidity 0.6.12; // a library for performing overflow-safe math, updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math) 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 <= uint128(-1), "BoringMath: uint128 Overflow"); c = uint128(a); } function to64(uint256 a) internal pure returns (uint64 c) { require(a <= uint64(-1), "BoringMath: uint64 Overflow"); c = uint64(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= uint32(-1), "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/interfaces/[email protected] pragma solidity 0.6.12; 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); function transferFrom(address owner, 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 @boringcrypto/boring-solidity/contracts/libraries/[email protected] pragma solidity 0.6.12; 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"); } } // File @boringcrypto/boring-solidity/contracts/[email protected] // Audit on 5-Jan-2021 by Keno and BoringCrypto // P1 - P3: OK pragma solidity 0.6.12; // solhint-disable avoid-low-level-calls // T1 - T4: OK 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 @boringcrypto/boring-solidity/contracts/[email protected] // Audit on 5-Jan-2021 by Keno and BoringCrypto // P1 - P3: OK pragma solidity 0.6.12; // Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol + Claimable.sol // Edited by BoringCrypto // T1 - T4: OK contract BoringOwnableData { // V1 - V5: OK address public owner; // V1 - V5: OK address public pendingOwner; } // T1 - T4: OK contract BoringOwnable is BoringOwnableData { // E1: OK event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor () public { owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } // F1 - F9: OK // C1 - C21: OK function transferOwnership(address newOwner, bool direct, bool renounce) public onlyOwner { if (direct) { // Checks require(newOwner != address(0) || renounce, "Ownable: zero address"); // Effects emit OwnershipTransferred(owner, newOwner); owner = newOwner; pendingOwner = address(0); } else { // Effects pendingOwner = newOwner; } } // F1 - F9: OK // C1 - C21: OK function claimOwnership() public { address _pendingOwner = pendingOwner; // Checks require(msg.sender == _pendingOwner, "Ownable: caller != pending owner"); // Effects emit OwnershipTransferred(owner, _pendingOwner); owner = _pendingOwner; pendingOwner = address(0); } // M1 - M5: OK // C1 - C21: OK modifier onlyOwner() { require(msg.sender == owner, "Ownable: caller is not the owner"); _; } } // File contracts/libraries/SignedSafeMath.sol pragma solidity 0.6.12; library SignedSafeMath { int256 constant private _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 contracts/interfaces/IRewarder.sol pragma solidity 0.6.12; interface IRewarder { using BoringERC20 for IERC20; function rewardToken() external returns(address); 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); } // File contracts/interfaces/IMasterChef.sol pragma solidity 0.6.12; pragma experimental ABIEncoderV2; interface IMasterChef { using BoringERC20 for IERC20; struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } struct PoolInfo { IERC20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. SUSHI to distribute per block. uint256 lastRewardBlock; // Last block number that SUSHI distribution occurs. uint256 accSushiPerShare; // Accumulated SUSHI per share, times 1e12. See below. } function poolInfo(uint256 pid) external view returns (IMasterChef.PoolInfo memory); function totalAllocPoint() external view returns (uint256); function deposit(uint256 _pid, uint256 _amount) external; } // File contracts/Masterchef.sol pragma solidity 0.6.12; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; /// @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. contract MasterChef is BoringOwnable, BoringBatchable, ReentrancyGuard { 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; IRewarder[] rewarders; } /// @notice Address of SUSHI contract. IERC20 public immutable SUSHI; /// @notice Info of each MCV2 pool. PoolInfo[] public poolInfo; /// @notice Address of the LP token for each MCV2 pool. IERC20[] public lpToken; /// @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; event Deposit(address indexed user, uint256 indexed pid, uint256 amount, address indexed to); 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); event LogSetPool(uint256 indexed pid, uint256 allocPoint); event LogUpdatePool(uint256 indexed pid, uint64 lastRewardTime, uint256 lpSupply, uint256 accSushiPerShare); event LogSushiPerSecond(uint256 sushiPerSecond); event LogRewarderAdded(uint256 indexed pid, IRewarder indexed rewarder); /// @param _sushi The SUSHI token contract address. constructor(IERC20 _sushi) public { SUSHI = _sushi; } /// @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. function add(uint256 allocPoint, IERC20 _lpToken) public onlyOwner { totalAllocPoint = totalAllocPoint.add(allocPoint); lpToken.push(_lpToken); poolInfo.push(PoolInfo({ allocPoint: allocPoint.to64(), lastRewardTime: block.timestamp.to64(), accSushiPerShare: 0, rewarders: (new IRewarder[](0)) })); emit LogPoolAddition(lpToken.length.sub(1), allocPoint, _lpToken); } /// @notice Add a new Rewarder instance to a given pool /// @param _pid The index of the pool. See `poolInfo`. /// @param _rewarder Address of the rewarder delegate. function addRewarder(uint256 _pid, IRewarder _rewarder) public onlyOwner { for( uint256 i = 0; i < poolInfo[_pid].rewarders.length; i++ ) { require(address(poolInfo[_pid].rewarders[i]) != address(_rewarder), "already added"); } poolInfo[_pid].rewarders.push(_rewarder); emit LogRewarderAdded(_pid, _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. function set(uint256 _pid, uint256 _allocPoint) public onlyOwner { totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint); poolInfo[_pid].allocPoint = _allocPoint.to64(); emit LogSetPool(_pid, _allocPoint); } /// @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 onlyOwner { sushiPerSecond = _sushiPerSecond; emit LogSushiPerSecond(_sushiPerSecond); } /// @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 > 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) nonReentrant public { PoolInfo memory pool = updatePool(pid); UserInfo storage user = userInfo[pid][to]; // Effects user.amount = user.amount.add(amount); user.rewardDebt = user.rewardDebt.add(int256(amount.mul(pool.accSushiPerShare) / ACC_SUSHI_PRECISION)); // Interactions for( uint256 i = 0; i < poolInfo[pid].rewarders.length; i++) { IRewarder _rewarder = poolInfo[pid].rewarders[i]; 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); } /// @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) nonReentrant 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 for( uint256 i = 0; i < poolInfo[pid].rewarders.length; i++) { IRewarder _rewarder = poolInfo[pid].rewarders[i]; 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) nonReentrant 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); } for( uint256 i = 0; i < poolInfo[pid].rewarders.length; i++) { IRewarder _rewarder = poolInfo[pid].rewarders[i]; 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) nonReentrant 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); for( uint256 i = 0; i < poolInfo[pid].rewarders.length; i++) { IRewarder _rewarder = poolInfo[pid].rewarders[i]; 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) nonReentrant public { UserInfo storage user = userInfo[pid][msg.sender]; uint256 amount = user.amount; user.amount = 0; user.rewardDebt = 0; for( uint256 i = 0; i < poolInfo[pid].rewarders.length; i++) { IRewarder _rewarder = poolInfo[pid].rewarders[i]; 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); } function getRewarder(uint256 _pid, uint256 _rid) public view returns(address) { return address(poolInfo[_pid].rewarders[_rid]); } }
// Sources flattened with hardhat v2.0.11 https://hardhat.org // File @boringcrypto/boring-solidity/contracts/interfaces/[email protected] // SPDX-License-Identifier: MIT pragma solidity 0.6.12; 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 @boringcrypto/boring-solidity/contracts/libraries/[email protected] 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"); } } // File contracts/interfaces/IRewarder.sol interface IRewarder { using BoringERC20 for IERC20; 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); } // File @boringcrypto/boring-solidity/contracts/libraries/[email protected] // a library for performing overflow-safe math, updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math) 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 <= uint128(-1), "BoringMath: uint128 Overflow"); c = uint128(a); } function to64(uint256 a) internal pure returns (uint64 c) { require(a <= uint64(-1), "BoringMath: uint64 Overflow"); c = uint64(a); } function to32(uint256 a) internal pure returns (uint32 c) { require(a <= uint32(-1), "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/[email protected] // Audit on 5-Jan-2021 by Keno and BoringCrypto // P1 - P3: OK pragma solidity 0.6.12; // Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol + Claimable.sol // Edited by BoringCrypto // T1 - T4: OK contract BoringOwnableData { // V1 - V5: OK address public owner; // V1 - V5: OK address public pendingOwner; } // T1 - T4: OK contract BoringOwnable is BoringOwnableData { // E1: OK event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor () public { owner = msg.sender; emit OwnershipTransferred(address(0), msg.sender); } // F1 - F9: OK // C1 - C21: OK function transferOwnership(address newOwner, bool direct, bool renounce) public onlyOwner { if (direct) { // Checks require(newOwner != address(0) || renounce, "Ownable: zero address"); // Effects emit OwnershipTransferred(owner, newOwner); owner = newOwner; pendingOwner = address(0); } else { // Effects pendingOwner = newOwner; } } // F1 - F9: OK // C1 - C21: OK function claimOwnership() public { address _pendingOwner = pendingOwner; // Checks require(msg.sender == _pendingOwner, "Ownable: caller != pending owner"); // Effects emit OwnershipTransferred(owner, _pendingOwner); owner = _pendingOwner; pendingOwner = address(0); } // M1 - M5: OK // C1 - C21: OK modifier onlyOwner() { require(msg.sender == owner, "Ownable: caller is not the owner"); _; } } // File @boringcrypto/boring-solidity/contracts/[email protected] // Audit on 5-Jan-2021 by Keno and BoringCrypto // P1 - P3: OK pragma solidity 0.6.12; pragma experimental ABIEncoderV2; // solhint-disable avoid-low-level-calls // T1 - T4: OK 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/libraries/SignedSafeMath.sol pragma solidity 0.6.12; library SignedSafeMath { int256 constant private _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 contracts/interfaces/IMasterChef.sol pragma solidity 0.6.12; interface IMasterChef { using BoringERC20 for IERC20; struct UserInfo { uint256 amount; // How many LP tokens the user has provided. uint256 rewardDebt; // Reward debt. See explanation below. } struct PoolInfo { IERC20 lpToken; // Address of LP token contract. uint256 allocPoint; // How many allocation points assigned to this pool. SUSHI to distribute per block. uint256 lastRewardBlock; // Last block number that SUSHI distribution occurs. uint256 accSushiPerShare; // Accumulated SUSHI per share, times 1e12. See below. } function poolInfo(uint256 pid) external view returns (IMasterChef.PoolInfo memory); function totalAllocPoint() external view returns (uint256); function deposit(uint256 _pid, uint256 _amount) external; } // File contracts/MasterChefV2.sol pragma solidity 0.6.12; 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); } /// @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. contract MasterChefV2 is BoringOwnable, 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 lastRewardBlock; uint64 allocPoint; } /// @notice Address of MCV1 contract. IMasterChef public immutable MASTER_CHEF; /// @notice Address of SUSHI contract. IERC20 public immutable SUSHI; /// @notice The index of MCV2 master pool in MCV1. uint256 public immutable MASTER_PID; // @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 constant MASTERCHEF_SUSHI_PER_BLOCK = 1e20; uint256 public constant ACC_SUSHI_PRECISION = 1e12; event Deposit(address indexed user, uint256 indexed pid, uint256 amount, address indexed to); 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 lastRewardBlock, uint256 lpSupply, uint256 accSushiPerShare); event LogInit(); /// @param _MASTER_CHEF The SushiSwap MCV1 contract address. /// @param _sushi The SUSHI token contract address. /// @param _MASTER_PID The pool ID of the dummy token on the base MCV1 contract. constructor(IMasterChef _MASTER_CHEF, IERC20 _sushi, uint256 _MASTER_PID) public { MASTER_CHEF = _MASTER_CHEF; SUSHI = _sushi; MASTER_PID = _MASTER_PID; } /// @notice Deposits a dummy token to `MASTER_CHEF` MCV1. This is required because MCV1 holds the minting rights for SUSHI. /// Any balance of transaction sender in `dummyToken` is transferred. /// The allocation point for the pool on MCV1 is the total allocation point for all pools that receive double incentives. /// @param dummyToken The address of the ERC-20 token to deposit into MCV1. function init(IERC20 dummyToken) external { uint256 balance = dummyToken.balanceOf(msg.sender); require(balance != 0, "MasterChefV2: Balance must exceed 0"); dummyToken.safeTransferFrom(msg.sender, address(this), balance); dummyToken.approve(address(MASTER_CHEF), balance); MASTER_CHEF.deposit(MASTER_PID, balance); emit LogInit(); } /// @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) public onlyOwner { uint256 lastRewardBlock = block.number; totalAllocPoint = totalAllocPoint.add(allocPoint); lpToken.push(_lpToken); rewarder.push(_rewarder); poolInfo.push(PoolInfo({ allocPoint: allocPoint.to64(), lastRewardBlock: lastRewardBlock.to64(), accSushiPerShare: 0 })); 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 onlyOwner { 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 Set the `migrator` contract. Can only be called by the owner. /// @param _migrator The contract address to set. function setMigrator(IMigratorChef _migrator) public onlyOwner { 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.number > pool.lastRewardBlock && lpSupply != 0) { uint256 blocks = block.number.sub(pool.lastRewardBlock); uint256 sushiReward = blocks.mul(sushiPerBlock()).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 Calculates and returns the `amount` of SUSHI per block. function sushiPerBlock() public view returns (uint256 amount) { amount = uint256(MASTERCHEF_SUSHI_PER_BLOCK) .mul(MASTER_CHEF.poolInfo(MASTER_PID).allocPoint) / MASTER_CHEF.totalAllocPoint(); } /// @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.number > pool.lastRewardBlock) { uint256 lpSupply = lpToken[pid].balanceOf(address(this)); if (lpSupply > 0) { uint256 blocks = block.number.sub(pool.lastRewardBlock); uint256 sushiReward = blocks.mul(sushiPerBlock()).mul(pool.allocPoint) / totalAllocPoint; pool.accSushiPerShare = pool.accSushiPerShare.add((sushiReward.mul(ACC_SUSHI_PRECISION) / lpSupply).to128()); } pool.lastRewardBlock = block.number.to64(); poolInfo[pid] = pool; emit LogUpdatePool(pid, pool.lastRewardBlock, 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]; // 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); } /// @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 Harvests SUSHI from `MASTER_CHEF` MCV1 and pool `MASTER_PID` to this MCV2 contract. function harvestFromMasterChef() public { MASTER_CHEF.deposit(MASTER_PID, 0); } /// @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); } } // File contracts/mocks/ComplexRewarderTime.sol pragma solidity 0.6.12; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; /// @author @0xKeno contract Rewarder is IRewarder, BoringOwnable, ReentrancyGuard{ using BoringMath for uint256; using BoringMath128 for uint128; using BoringERC20 for IERC20; IERC20 public rewardToken; /// @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; uint256 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; } /// @notice Info of each pool. mapping (uint256 => PoolInfo) public poolInfo; uint256[] public poolIds; /// @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 rewardPerSecond; uint256 public constant ACC_TOKEN_PRECISION = 1e12; address public immutable MASTERCHEF_V2; modifier onlyMCV2 { require( msg.sender == MASTERCHEF_V2, "Only MCV2 can call this function." ); _; } address public funder; modifier onlyFunder() { require(msg.sender == funder, "Ownable: caller is not the funder"); _; } event LogOnReward(address indexed user, uint256 indexed pid, uint256 amount, address indexed to); event LogPoolAddition(uint256 indexed pid, uint256 allocPoint); event LogSetPool(uint256 indexed pid, uint256 allocPoint); event LogUpdatePool(uint256 indexed pid, uint64 lastRewardTime, uint256 lpSupply, uint256 accSushiPerShare); event LogRewardPerSecond(uint256 rewardPerSecond); event LogInit(); constructor (IERC20 _rewardToken, uint256 _rewardPerSecond, address _MASTERCHEF_V2) public { rewardToken = _rewardToken; rewardPerSecond = _rewardPerSecond; MASTERCHEF_V2 = _MASTERCHEF_V2; funder = msg.sender; } function onSushiReward (uint256 pid, address _user, address to, uint256, uint256 lpToken) onlyMCV2 nonReentrant override external { PoolInfo memory pool = updatePool(pid); UserInfo storage user = userInfo[pid][_user]; uint256 pending; if (user.amount > 0) { pending = (user.amount.mul(pool.accSushiPerShare) / ACC_TOKEN_PRECISION).sub( user.rewardDebt ); rewardToken.safeTransfer(to, pending); } user.amount = lpToken; user.rewardDebt = lpToken.mul(pool.accSushiPerShare) / ACC_TOKEN_PRECISION; emit LogOnReward(_user, pid, pending, to); } function pendingTokens(uint256 pid, address user, uint256) override external view returns (IERC20[] memory rewardTokens, uint256[] memory rewardAmounts) { IERC20[] memory _rewardTokens = new IERC20[](1); _rewardTokens[0] = (rewardToken); uint256[] memory _rewardAmounts = new uint256[](1); _rewardAmounts[0] = pendingToken(pid, user); return (_rewardTokens, _rewardAmounts); } /// @notice Sets the sushi per second to be distributed. Can only be called by the owner. /// @param _rewardPerSecond The amount of Sushi to be distributed per second. function setRewardPerSecond(uint256 _rewardPerSecond) public onlyOwner { rewardPerSecond = _rewardPerSecond; emit LogRewardPerSecond(_rewardPerSecond); } /// @notice Returns the number of MCV2 pools. function poolLength() public view returns (uint256 pools) { pools = poolIds.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 _pid Pid on MCV2 function add(uint256 allocPoint, uint256 _pid) public onlyOwner { require(poolInfo[_pid].lastRewardTime == 0, "Pool already exists"); uint256 lastRewardTime = block.timestamp; totalAllocPoint = totalAllocPoint.add(allocPoint); poolInfo[_pid] = PoolInfo({ allocPoint: allocPoint.to64(), lastRewardTime: lastRewardTime.to64(), accSushiPerShare: 0 }); poolIds.push(_pid); emit LogPoolAddition(_pid, allocPoint); } /// @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. function set(uint256 _pid, uint256 _allocPoint) public onlyOwner { totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint); poolInfo[_pid].allocPoint = _allocPoint.to64(); emit LogSetPool(_pid, _allocPoint); } /// @notice View function to see pending Token /// @param _pid The index of the pool. See `poolInfo`. /// @param _user Address of user. /// @return pending SUSHI reward for a given user. function pendingToken(uint256 _pid, address _user) public view returns (uint256 pending) { PoolInfo memory pool = poolInfo[_pid]; UserInfo storage user = userInfo[_pid][_user]; uint256 accSushiPerShare = pool.accSushiPerShare; uint256 lpSupply = MasterChefV2(MASTERCHEF_V2).lpToken(_pid).balanceOf(MASTERCHEF_V2); if (block.timestamp > pool.lastRewardTime && lpSupply != 0) { uint256 time = block.timestamp.sub(pool.lastRewardTime); uint256 sushiReward = time.mul(rewardPerSecond).mul(pool.allocPoint) / totalAllocPoint; accSushiPerShare = accSushiPerShare.add(sushiReward.mul(ACC_TOKEN_PRECISION) / lpSupply); } pending = (user.amount.mul(accSushiPerShare) / ACC_TOKEN_PRECISION).sub(user.rewardDebt); } /// @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 > pool.lastRewardTime) { uint256 lpSupply = MasterChefV2(MASTERCHEF_V2).lpToken(pid).balanceOf(MASTERCHEF_V2); if (lpSupply > 0) { uint256 time = block.timestamp.sub(pool.lastRewardTime); uint256 sushiReward = time.mul(rewardPerSecond).mul(pool.allocPoint) / totalAllocPoint; pool.accSushiPerShare = pool.accSushiPerShare.add((sushiReward.mul(ACC_TOKEN_PRECISION) / lpSupply).to128()); } pool.lastRewardTime = block.timestamp.to64(); poolInfo[pid] = pool; emit LogUpdatePool(pid, pool.lastRewardTime, lpSupply, pool.accSushiPerShare); } } function transferFunder(address newFunder) public onlyFunder { funder = newFunder; } function reclaimTokens(uint256 amount, address payable to) public onlyFunder { rewardToken.safeTransfer(to, amount); } }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
[{"inputs":[{"internalType":"contract IERC20","name":"_rewardToken","type":"address"},{"internalType":"uint256","name":"_rewardPerSecond","type":"uint256"},{"internalType":"address","name":"_MASTERCHEF_V2","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"LogInit","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":"LogOnReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"LogPoolAddition","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"rewardPerSecond","type":"uint256"}],"name":"LogRewardPerSecond","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"}],"name":"LogSetPool","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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"ACC_TOKEN_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MASTERCHEF_V2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"funder","outputs":[{"internalType":"address","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"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"lpToken","type":"uint256"}],"name":"onSushiReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingToken","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pid","type":"uint256"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"pendingTokens","outputs":[{"internalType":"contract IERC20[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"rewardAmounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"pools","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"to","type":"address"}],"name":"reclaimTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rewardPerSecond","type":"uint256"}],"name":"setRewardPerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newFunder","type":"address"}],"name":"transferFunder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"bool","name":"direct","type":"bool"},{"internalType":"bool","name":"renounce","type":"bool"}],"name":"transferOwnership","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":"struct Rewarder.PoolInfo","name":"pool","type":"tuple"}],"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":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162003246380380620032468339818101604052810190620000379190620001e8565b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600160028190555082600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816008819055508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b8152505033600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050620002de565b600081519050620001b48162000290565b92915050565b600081519050620001cb81620002aa565b92915050565b600081519050620001e281620002c4565b92915050565b600080600060608486031215620001fe57600080fd5b60006200020e86828701620001ba565b93505060206200022186828701620001d1565b92505060406200023486828701620001a3565b9150509250925092565b60006200024b8262000266565b9050919050565b60006200025f826200023e565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6200029b816200023e565b8114620002a757600080fd5b50565b620002b58162000252565b8114620002c157600080fd5b50565b620002cf8162000286565b8114620002db57600080fd5b50565b60805160601c612f316200031560003980610a2f5280610af35280610f0f5280610fd352806112be52806117435250612f316000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c806366da5815116100c357806393f1a40b1161007c57806393f1a40b146103a1578063d63b3c49146103d2578063e30c397814610403578063e4858a4014610421578063eea016041461043d578063f7c618c11461045b57610158565b806366da5815146102e157806369883b4e146102fd578063771602f71461032d5780638bf63742146103495780638da5cb5b146103655780638f10369a1461038357610158565b806348e43af41161011557806348e43af4146102215780634e71e0c81461025157806351eb05a61461025b57806357a5b58c1461028b5780635a894421146102a757806361ce7db2146102c557610158565b8063041ae8801461015d578063078dfbe71461017b578063081e3eda146101975780631526fe27146101b557806317caf6f1146101e75780631ab06ee514610205575b600080fd5b610165610479565b60405161017291906129e7565b60405180910390f35b6101956004803603810190610190919061219d565b61049f565b005b61019f6106f3565b6040516101ac9190612c6f565b60405180910390f35b6101cf60048036038101906101ca9190612283565b610700565b6040516101de93929190612c38565b60405180910390f35b6101ef61076e565b6040516101fc9190612c6f565b60405180910390f35b61021f600480360381019061021a9190612413565b610774565b005b61023b600480360381019061023691906122d5565b6108e4565b6040516102489190612c6f565b60405180910390f35b610259610c8b565b005b61027560048036038101906102709190612283565b610e1f565b6040516102829190612c1d565b60405180910390f35b6102a560048036038101906102a091906121ec565b61127c565b005b6102af6112bc565b6040516102bc91906129e7565b60405180910390f35b6102df60048036038101906102da9190612311565b6112e0565b005b6102fb60048036038101906102f69190612283565b6113c1565b005b61031760048036038101906103129190612283565b611490565b6040516103249190612c6f565b60405180910390f35b61034760048036038101906103429190612413565b6114b1565b005b610363600480360381019061035e919061234d565b611741565b005b61036d6119f1565b60405161037a91906129e7565b60405180910390f35b61038b611a15565b6040516103989190612c6f565b60405180910390f35b6103bb60048036038101906103b691906122d5565b611a1b565b6040516103c9929190612c8a565b60405180910390f35b6103ec60048036038101906103e791906123c4565b611a4c565b6040516103fa929190612a2b565b60405180910390f35b61040b611b84565b60405161041891906129e7565b60405180910390f35b61043b60048036038101906104369190612174565b611baa565b005b610445611c7e565b6040516104529190612c6f565b60405180910390f35b610463611c87565b6040516104709190612a62565b60405180910390f35b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461052d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161052490612b7d565b60405180910390fd5b81156106ac57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614158061056c5750805b6105ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105a290612afd565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506106ee565b82600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b505050565b6000600580549050905090565b60046020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a900467ffffffffffffffff16908060000160189054906101000a900467ffffffffffffffff16905083565b60075481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610802576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f990612b7d565b60405180910390fd5b61085d8161084f6004600086815260200190815260200160002060000160189054906101000a900467ffffffffffffffff1667ffffffffffffffff16600754611cad90919063ffffffff16565b611cfd90919063ffffffff16565b60078190555061086c81611d4d565b6004600084815260200190815260200160002060000160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550817f942cc7e17a17c164bd977f32ab8c54265d5b9d481e4e352bf874f1e568874e7c826040516108d89190612c6f565b60405180910390a25050565b60006108ee612050565b600460008581526020019081526020016000206040518060600160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016000820160189054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681525050905060006006600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600082600001516fffffffffffffffffffffffffffffffff16905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166378ed5d1f886040518263ffffffff1660e01b8152600401610a869190612c6f565b60206040518083038186803b158015610a9e57600080fd5b505afa158015610ab2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ad6919061225a565b73ffffffffffffffffffffffffffffffffffffffff166370a082317f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b8152600401610b2e91906129e7565b60206040518083038186803b158015610b4657600080fd5b505afa158015610b5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b7e91906122ac565b9050836020015167ffffffffffffffff1642118015610b9e575060008114155b15610c44576000610bc6856020015167ffffffffffffffff1642611cad90919063ffffffff16565b90506000600754610c02876040015167ffffffffffffffff16610bf460085486611dc490919063ffffffff16565b611dc490919063ffffffff16565b81610c0957fe5b049050610c3f83610c2864e8d4a5100084611dc490919063ffffffff16565b81610c2f57fe5b0485611cfd90919063ffffffff16565b935050505b610c7f836001015464e8d4a51000610c69858760000154611dc490919063ffffffff16565b81610c7057fe5b04611cad90919063ffffffff16565b94505050505092915050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1790612b9d565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b610e27612050565b600460008381526020019081526020016000206040518060600160405290816000820160009054906101000a90046fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff166fffffffffffffffffffffffffffffffff1681526020016000820160109054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff1681526020016000820160189054906101000a900467ffffffffffffffff1667ffffffffffffffff1667ffffffffffffffff16815250509050806020015167ffffffffffffffff164211156112775760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166378ed5d1f846040518263ffffffff1660e01b8152600401610f669190612c6f565b60206040518083038186803b158015610f7e57600080fd5b505afa158015610f92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fb6919061225a565b73ffffffffffffffffffffffffffffffffffffffff166370a082317f00000000000000000000000000000000000000000000000000000000000000006040518263ffffffff1660e01b815260040161100e91906129e7565b60206040518083038186803b15801561102657600080fd5b505afa15801561103a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105e91906122ac565b9050600081111561115557600061108c836020015167ffffffffffffffff1642611cad90919063ffffffff16565b905060006007546110c8856040015167ffffffffffffffff166110ba60085486611dc490919063ffffffff16565b611dc490919063ffffffff16565b816110cf57fe5b0490506111236110fe846110f164e8d4a5100085611dc490919063ffffffff16565b816110f857fe5b04611e26565b85600001516fffffffffffffffffffffffffffffffff16611ea590919063ffffffff16565b84600001906fffffffffffffffffffffffffffffffff1690816fffffffffffffffffffffffffffffffff168152505050505b61115e42611d4d565b826020019067ffffffffffffffff16908167ffffffffffffffff1681525050816004600085815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060408201518160000160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550905050827f0fc9545022a542541ad085d091fb09a2ab36fee366a4576ab63714ea907ad353836020015183856000015160405161126d93929190612cb3565b60405180910390a2505b919050565b600082829050905060005b818110156112b6576112aa84848381811061129e57fe5b90506020020135610e1f565b50806001019050611287565b50505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611370576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136790612b5d565b60405180910390fd5b6113bd8183600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611f199092919063ffffffff16565b5050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461144f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161144690612b7d565b60405180910390fd5b806008819055507fde89cb17ac7f58f94792b3e91e086ed85403819c24ceea882491f960ccb1a278816040516114859190612c6f565b60405180910390a150565b6005818154811061149d57fe5b906000526020600020016000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461153f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161153690612b7d565b60405180910390fd5b60006004600083815260200190815260200160002060000160109054906101000a900467ffffffffffffffff1667ffffffffffffffff16146115b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ad90612a9d565b60405180910390fd5b60004290506115d083600754611cfd90919063ffffffff16565b600781905550604051806060016040528060006fffffffffffffffffffffffffffffffff16815260200161160383611d4d565b67ffffffffffffffff16815260200161161b85611d4d565b67ffffffffffffffff168152506004600084815260200190815260200160002060008201518160000160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060208201518160000160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060408201518160000160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050506005829080600181540180825580915050600190039060005260206000200160009091909190915055817f38410508059921573ab9ebdca2a5034be738d236366b8f32de4434ea95ed3c81846040516117349190612c6f565b60405180910390a2505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146117cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117c690612add565b60405180910390fd5b600280541415611814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161180b90612bdd565b60405180910390fd5b60028081905550611823612050565b61182c86610e1f565b905060006006600088815260200190815260200160002060008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008082600001541115611931576118e1826001015464e8d4a510006118cb86600001516fffffffffffffffffffffffffffffffff168660000154611dc490919063ffffffff16565b816118d257fe5b04611cad90919063ffffffff16565b90506119308682600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16611f199092919063ffffffff16565b5b83826000018190555064e8d4a5100061196984600001516fffffffffffffffffffffffffffffffff1686611dc490919063ffffffff16565b8161197057fe5b0482600101819055508573ffffffffffffffffffffffffffffffffffffffff16888873ffffffffffffffffffffffffffffffffffffffff167f2ece88ca2bc08dd018db50e1d25a20bf1241e5fab1c396caa51f01a54bd2f75b846040516119d79190612c6f565b60405180910390a450505060016002819055505050505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60085481565b6006602052816000526040600020602052806000526040600020600091509150508060000154908060010154905082565b6060806060600167ffffffffffffffff81118015611a6957600080fd5b50604051908082528060200260200182016040528015611a985781602001602082028036833780820191505090505b509050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681600081518110611acb57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506060600167ffffffffffffffff81118015611b1f57600080fd5b50604051908082528060200260200182016040528015611b4e5781602001602082028036833780820191505090505b509050611b5b87876108e4565b81600081518110611b6857fe5b6020026020010181815250508181935093505050935093915050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611c3a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c3190612b5d565b60405180910390fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b64e8d4a5100081565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000828284039150811115611cf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cee90612a7d565b60405180910390fd5b92915050565b6000818284019150811015611d47576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3e90612b3d565b60405180910390fd5b92915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff16821115611dbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611db390612bbd565b60405180910390fd5b819050919050565b600080821480611de15750828283850292508281611dde57fe5b04145b611e20576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e1790612bfd565b60405180910390fd5b92915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6fffffffffffffffffffffffffffffffff16821115611e9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e9490612b1d565b60405180910390fd5b819050919050565b6000816fffffffffffffffffffffffffffffffff168284019150816fffffffffffffffffffffffffffffffff161015611f13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f0a90612b3d565b60405180910390fd5b92915050565b600060608473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb8585604051602401611f4c929190612a02565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611f9a91906129d0565b6000604051808303816000865af19150503d8060008114611fd7576040519150601f19603f3d011682016040523d82523d6000602084013e611fdc565b606091505b509150915081801561200a57506000815114806120095750808060200190518101906120089190612231565b5b5b612049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161204090612abd565b60405180910390fd5b5050505050565b604051806060016040528060006fffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff1681525090565b6000813590506120a681612e88565b92915050565b6000813590506120bb81612e9f565b92915050565b60008083601f8401126120d357600080fd5b8235905067ffffffffffffffff8111156120ec57600080fd5b60208301915083602082028301111561210457600080fd5b9250929050565b60008135905061211a81612eb6565b92915050565b60008151905061212f81612eb6565b92915050565b60008151905061214481612ecd565b92915050565b60008135905061215981612ee4565b92915050565b60008151905061216e81612ee4565b92915050565b60006020828403121561218657600080fd5b600061219484828501612097565b91505092915050565b6000806000606084860312156121b257600080fd5b60006121c086828701612097565b93505060206121d18682870161210b565b92505060406121e28682870161210b565b9150509250925092565b600080602083850312156121ff57600080fd5b600083013567ffffffffffffffff81111561221957600080fd5b612225858286016120c1565b92509250509250929050565b60006020828403121561224357600080fd5b600061225184828501612120565b91505092915050565b60006020828403121561226c57600080fd5b600061227a84828501612135565b91505092915050565b60006020828403121561229557600080fd5b60006122a38482850161214a565b91505092915050565b6000602082840312156122be57600080fd5b60006122cc8482850161215f565b91505092915050565b600080604083850312156122e857600080fd5b60006122f68582860161214a565b925050602061230785828601612097565b9150509250929050565b6000806040838503121561232457600080fd5b60006123328582860161214a565b9250506020612343858286016120ac565b9150509250929050565b600080600080600060a0868803121561236557600080fd5b60006123738882890161214a565b955050602061238488828901612097565b945050604061239588828901612097565b93505060606123a68882890161214a565b92505060806123b78882890161214a565b9150509295509295909350565b6000806000606084860312156123d957600080fd5b60006123e78682870161214a565b93505060206123f886828701612097565b92505060406124098682870161214a565b9150509250925092565b6000806040838503121561242657600080fd5b60006124348582860161214a565b92505060206124458582860161214a565b9150509250929050565b600061245b838361257b565b60208301905092915050565b60006124738383612994565b60208301905092915050565b61248881612d83565b82525050565b600061249982612d0a565b6124a38185612d45565b93506124ae83612cea565b8060005b838110156124df5781516124c6888261244f565b97506124d183612d2b565b9250506001810190506124b2565b5085935050505092915050565b60006124f782612d15565b6125018185612d56565b935061250c83612cfa565b8060005b8381101561253d5781516125248882612467565b975061252f83612d38565b925050600181019050612510565b5085935050505092915050565b600061255582612d20565b61255f8185612d67565b935061256f818560208601612e55565b80840191505092915050565b61258481612e1f565b82525050565b61259381612e1f565b82525050565b60006125a6601583612d72565b91507f426f72696e674d6174683a20556e646572666c6f7700000000000000000000006000830152602082019050919050565b60006125e6601383612d72565b91507f506f6f6c20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000612626601c83612d72565b91507f426f72696e6745524332303a205472616e73666572206661696c6564000000006000830152602082019050919050565b6000612666602183612d72565b91507f4f6e6c79204d4356322063616e2063616c6c20746869732066756e6374696f6e60008301527f2e000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006126cc601583612d72565b91507f4f776e61626c653a207a65726f206164647265737300000000000000000000006000830152602082019050919050565b600061270c601c83612d72565b91507f426f72696e674d6174683a2075696e74313238204f766572666c6f77000000006000830152602082019050919050565b600061274c601883612d72565b91507f426f72696e674d6174683a20416464204f766572666c6f7700000000000000006000830152602082019050919050565b600061278c602183612d72565b91507f4f776e61626c653a2063616c6c6572206973206e6f74207468652066756e646560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006127f2602083612d72565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000612832602083612d72565b91507f4f776e61626c653a2063616c6c657220213d2070656e64696e67206f776e65726000830152602082019050919050565b6000612872601b83612d72565b91507f426f72696e674d6174683a2075696e743634204f766572666c6f7700000000006000830152602082019050919050565b60006128b2601f83612d72565b91507f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006000830152602082019050919050565b60006128f2601883612d72565b91507f426f72696e674d6174683a204d756c204f766572666c6f7700000000000000006000830152602082019050919050565b60608201600082015161293b6000850182612967565b50602082015161294e60208501826129b2565b50604082015161296160408501826129b2565b50505050565b61297081612dc5565b82525050565b61297f81612dc5565b82525050565b61298e81612e43565b82525050565b61299d81612e01565b82525050565b6129ac81612e01565b82525050565b6129bb81612e0b565b82525050565b6129ca81612e0b565b82525050565b60006129dc828461254a565b915081905092915050565b60006020820190506129fc600083018461247f565b92915050565b6000604082019050612a17600083018561247f565b612a2460208301846129a3565b9392505050565b60006040820190508181036000830152612a45818561248e565b90508181036020830152612a5981846124ec565b90509392505050565b6000602082019050612a77600083018461258a565b92915050565b60006020820190508181036000830152612a9681612599565b9050919050565b60006020820190508181036000830152612ab6816125d9565b9050919050565b60006020820190508181036000830152612ad681612619565b9050919050565b60006020820190508181036000830152612af681612659565b9050919050565b60006020820190508181036000830152612b16816126bf565b9050919050565b60006020820190508181036000830152612b36816126ff565b9050919050565b60006020820190508181036000830152612b568161273f565b9050919050565b60006020820190508181036000830152612b768161277f565b9050919050565b60006020820190508181036000830152612b96816127e5565b9050919050565b60006020820190508181036000830152612bb681612825565b9050919050565b60006020820190508181036000830152612bd681612865565b9050919050565b60006020820190508181036000830152612bf6816128a5565b9050919050565b60006020820190508181036000830152612c16816128e5565b9050919050565b6000606082019050612c326000830184612925565b92915050565b6000606082019050612c4d6000830186612976565b612c5a60208301856129c1565b612c6760408301846129c1565b949350505050565b6000602082019050612c8460008301846129a3565b92915050565b6000604082019050612c9f60008301856129a3565b612cac60208301846129a3565b9392505050565b6000606082019050612cc860008301866129c1565b612cd560208301856129a3565b612ce26040830184612985565b949350505050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b6000612d8e82612de1565b9050919050565b6000612da082612de1565b9050919050565b60008115159050919050565b6000612dbe82612d83565b9050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600067ffffffffffffffff82169050919050565b6000612e2a82612e31565b9050919050565b6000612e3c82612de1565b9050919050565b6000612e4e82612dc5565b9050919050565b60005b83811015612e73578082015181840152602081019050612e58565b83811115612e82576000848401525b50505050565b612e9181612d83565b8114612e9c57600080fd5b50565b612ea881612d95565b8114612eb357600080fd5b50565b612ebf81612da7565b8114612eca57600080fd5b50565b612ed681612db3565b8114612ee157600080fd5b50565b612eed81612e01565b8114612ef857600080fd5b5056fea26469706673582212205b2776e192b3bfeb55fc7505d3973c0560e6b18c19e8fdc1fb5ad83356fbbff364736f6c634300060c003300000000000000000000000068286607a1d43602d880d349187c3c48c0fd05e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e2d8f84605d32a2cbf302e30bfd2387badf35dd
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000068286607a1d43602d880d349187c3c48c0fd05e600000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e2d8f84605d32a2cbf302e30bfd2387badf35dd
-----Decoded View---------------
Arg [0] : _rewardToken (address): 0x68286607a1d43602d880d349187c3c48c0fd05e6
Arg [1] : _rewardPerSecond (uint256): 0
Arg [2] : _MASTERCHEF_V2 (address): 0x1e2d8f84605d32a2cbf302e30bfd2387badf35dd
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000068286607a1d43602d880d349187c3c48c0fd05e6
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 0000000000000000000000001e2d8f84605d32a2cbf302e30bfd2387badf35dd
Deployed ByteCode Sourcemap
27317:7716:2:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28739:21;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5475:459;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31091:97;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28102:45;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;28407:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32178:263;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32650:800;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5979:338;;;:::i;:::-;;33995:802;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33628:188;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;28537:38;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34905:125;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;30862:173;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;28154:24;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31437:507;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;29567:683;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;5068:20;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28444:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28242:66;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;30260:420;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;5113:27;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34803:96;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;28480:50;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;27492:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;28739:21;;;;;;;;;;;;;:::o;5475:459::-;6415:5;;;;;;;;;;6401:19;;:10;:19;;;6393:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;5579:6:::1;5575:353;;;5651:1;5631:22;;:8;:22;;;;:34;;;;5657:8;5631:34;5623:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5762:8;5734:37;;5755:5;::::0;::::1;;;;;;;;5734:37;;;;;;;;;;;;5793:8;5785:5;::::0;:16:::1;;;;;;;;;;;;;;;;;;5838:1;5815:12;;:25;;;;;;;;;;;;;;;;;;5575:353;;;5909:8;5894:12;;:23;;;;;;;;;;;;;;;;;;5575:353;5475:459:::0;;;:::o;31091:97::-;31134:13;31167:7;:14;;;;31159:22;;31091:97;:::o;28102:45::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;28407:30::-;;;;:::o;32178:263::-;6415:5;;;;;;;;;;6401:19;;:10;:19;;;6393:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;32271:63:::1;32322:11;32271:46;32291:8;:14;32300:4;32291:14;;;;;;;;;;;:25;;;;;;;;;;;;32271:46;;:15;;:19;;:46;;;;:::i;:::-;:50;;:63;;;;:::i;:::-;32253:15;:81;;;;32372:18;:11;:16;:18::i;:::-;32344:8;:14;32353:4;32344:14;;;;;;;;;;;:25;;;:46;;;;;;;;;;;;;;;;;;32416:4;32405:29;32422:11;32405:29;;;;;;:::i;:::-;;;;;;;;32178:263:::0;;:::o;32650:800::-;32722:15;32749:20;;:::i;:::-;32772:8;:14;32781:4;32772:14;;;;;;;;;;;32749:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32796:21;32820:8;:14;32829:4;32820:14;;;;;;;;;;;:21;32835:5;32820:21;;;;;;;;;;;;;;;32796:45;;32851:24;32878:4;:21;;;32851:48;;;;32909:16;32941:13;32928:35;;;32964:4;32928:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:51;;;32980:13;32928:66;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;32909:85;;33026:4;:19;;;33008:37;;:15;:37;:54;;;;;33061:1;33049:8;:13;;33008:54;33004:342;;;33078:12;33093:40;33113:4;:19;;;33093:40;;:15;:19;;:40;;;;:::i;:::-;33078:55;;33147:19;33218:15;;33169:46;33199:4;:15;;;33169:46;;:25;33178:15;;33169:4;:8;;:25;;;;:::i;:::-;:29;;:46;;;;:::i;:::-;:64;;;;;;33147:86;;33266:69;33326:8;33287:36;28526:4;33287:11;:15;;:36;;;;:::i;:::-;:47;;;;;;33266:16;:20;;:69;;;;:::i;:::-;33247:88;;33004:342;;;33365:78;33427:4;:15;;;28526:4;33366:33;33382:16;33366:4;:11;;;:15;;:33;;;;:::i;:::-;:55;;;;;;33365:61;;:78;;;;:::i;:::-;33355:88;;32650:800;;;;;;;;:::o;5979:338::-;6022:21;6046:12;;;;;;;;;;;6022:36;;6117:13;6103:27;;:10;:27;;;6095:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;6230:13;6202:42;;6223:5;;;;;;;;;;6202:42;;;;;;;;;;;;6262:13;6254:5;;:21;;;;;;;;;;;;;;;;;;6308:1;6285:12;;:25;;;;;;;;;;;;;;;;;;5979:338;:::o;33995:802::-;34044:20;;:::i;:::-;34083:8;:13;34092:3;34083:13;;;;;;;;;;;34076:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34128:4;:19;;;34110:37;;:15;:37;34106:685;;;34163:16;34195:13;34182:35;;;34218:3;34182:40;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:50;;;34233:13;34182:65;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34163:84;;34277:1;34266:8;:12;34262:336;;;34298:12;34313:40;34333:4;:19;;;34313:40;;:15;:19;;:40;;;;:::i;:::-;34298:55;;34371:19;34442:15;;34393:46;34423:4;:15;;;34393:46;;:25;34402:15;;34393:4;:8;;:25;;;;:::i;:::-;:29;;:46;;;;:::i;:::-;:64;;;;;;34371:86;;34499:84;34525:57;34565:8;34526:36;28526:4;34526:11;:15;;:36;;;;:::i;:::-;:47;;;;;;34525:55;:57::i;:::-;34499:4;:21;;;:25;;;;:84;;;;:::i;:::-;34475:4;:21;;:108;;;;;;;;;;;34262:336;;;34633:22;:15;:20;:22::i;:::-;34611:4;:19;;:44;;;;;;;;;;;34685:4;34669:8;:13;34678:3;34669:13;;;;;;;;;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34722:3;34708:72;34727:4;:19;;;34748:8;34758:4;:21;;;34708:72;;;;;;;;:::i;:::-;;;;;;;;34106:685;;33995:802;;;:::o;33628:188::-;33697:11;33711:4;;:11;;33697:25;;33737:9;33732:78;33756:3;33752:1;:7;33732:78;;;33780:19;33791:4;;33796:1;33791:7;;;;;;;;;;;;;33780:10;:19::i;:::-;;33761:3;;;;;33732:78;;;;33628:188;;;:::o;28537:38::-;;;:::o;34905:125::-;28821:6;;;;;;;;;;;28807:20;;:10;:20;;;28799:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;34987:36:::1;35012:2;35016:6;34987:11;;;;;;;;;;;:24;;;;:36;;;;;:::i;:::-;34905:125:::0;;:::o;30862:173::-;6415:5;;;;;;;;;;6401:19;;:10;:19;;;6393:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;30961:16:::1;30943:15;:34;;;;30992:36;31011:16;30992:36;;;;;;:::i;:::-;;;;;;;;30862:173:::0;:::o;28154:24::-;;;;;;;;;;;;;;;;;;;;;;;;;:::o;31437:507::-;6415:5;;;;;;;;;;6401:19;;:10;:19;;;6393:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;31552:1:::1;31519:8;:14;31528:4;31519:14;;;;;;;;;;;:29;;;;;;;;;;;;:34;;;31511:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;31587:22;31612:15;31587:40;;31655:31;31675:10;31655:15;;:19;;:31;;;;:::i;:::-;31637:15;:49;;;;31714:147;;;;;;;;31849:1;31714:147;;;;;;31796:21;:14;:19;:21::i;:::-;31714:147;;;;;;31749:17;:10;:15;:17::i;:::-;31714:147;;;;::::0;31697:8:::1;:14;31706:4;31697:14;;;;;;;;;;;:164;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31871:7;31884:4;31871:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31920:4;31904:33;31926:10;31904:33;;;;;;:::i;:::-;;;;;;;;6467:1;31437:507:::0;;:::o;29567:683::-;28645:13;28631:27;;:10;:27;;;28610:107;;;;;;;;;;;;:::i;:::-;;;;;;;;;1688:1:0::1;2277:7:::0;::::1;:19;;2269:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;1688:1;2407:7:::0;:18:::1;;;;29707:20:2::2;;:::i;:::-;29730:15;29741:3;29730:10;:15::i;:::-;29707:38;;29755:21;29779:8;:13;29788:3;29779:13;;;;;;;;;;;:20;29793:5;29779:20;;;;;;;;;;;;;;;29755:44;;29809:15;29852:1:::0;29838:4:::2;:11;;;:15;29834:244;;;29895:121;29983:4;:15;;;28526:4;29896:38;29912:4;:21;;;29896:38;;:4;:11;;;:15;;:38;;;;:::i;:::-;:60;;;;;;29895:66;;:121;;;;:::i;:::-;29869:147;;30030:37;30055:2;30059:7;30030:11;;;;;;;;;;;:24;;;;:37;;;;;:::i;:::-;29834:244;30101:7;30087:4;:11;;:21;;;;28526:4;30136:34;30148:4;:21;;;30136:34;;:7;:11;;:34;;;;:::i;:::-;:56;;;;;;30118:4;:15;;:74;;;;30240:2;30207:36;;30226:3;30219:5;30207:36;;;30231:7;30207:36;;;;;;:::i;:::-;;;;;;;;2436:1:0;;;1645::::1;2580:7;:22;;;;29567:683:2::0;;;;;:::o;5068:20::-;;;;;;;;;;;;:::o;28444:30::-;;;;:::o;28242:66::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;30260:420::-;30351:28;30381:30;30423:29;30468:1;30455:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30423:47;;30500:11;;;;;;;;;;;30480:13;30494:1;30480:16;;;;;;;;;;;;;:32;;;;;;;;;;;30522:31;30570:1;30556:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30522:50;;30602:23;30615:3;30620:4;30602:12;:23::i;:::-;30582:14;30597:1;30582:17;;;;;;;;;;;;;:43;;;;;30643:13;30658:14;30635:38;;;;;;30260:420;;;;;;:::o;5113:27::-;;;;;;;;;;;;;:::o;34803:96::-;28821:6;;;;;;;;;;;28807:20;;:10;:20;;;28799:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;34883:9:::1;34874:6;;:18;;;;;;;;;;;;;;;;;;34803:96:::0;:::o;28480:50::-;28526:4;28480:50;:::o;27492:25::-;;;;;;;;;;;;;:::o;3102:122::-;3160:9;3195:1;3189;3185;:5;3181:9;;;3180:16;;3172:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;3102:122;;;;:::o;2972:125::-;3030:9;3065:1;3059;3055;:5;3051:9;;;3050:16;;3042:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;2972:125;;;;:::o;3534:153::-;3582:8;3622:2;3610:15;;:1;:15;;3602:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;3678:1;3667:13;;3534:153;;;:::o;3229:137::-;3287:9;3312:1;3307;:6;:28;;;;3334:1;3329;3326;3322;:5;3318:9;;;3317:13;;;;;;:18;3307:28;3299:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;3229:137;;;;:::o;3371:158::-;3420:9;3462:2;3449:16;;:1;:16;;3441:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;3520:1;3508:14;;3371:158;;;:::o;3877:125::-;3935:9;3970:1;3955:16;;3964:1;3960;:5;3956:9;;;3955:16;;;;3947:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;3877:125;;;;:::o;1736:301::-;1820:12;1834:17;1863:5;1855:19;;1898:10;1910:2;1914:6;1875:46;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1855:67;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1819:103;;;;1940:7;:57;;;;;1967:1;1952:4;:11;:16;:44;;;;1983:4;1972:24;;;;;;;;;;;;:::i;:::-;1952:44;1940:57;1932:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;1736:301;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130::-;;85:6;72:20;63:29;;97:33;124:5;97:33;:::i;:::-;57:78;;;;:::o;142:146::-;;230:6;217:20;208:29;;242:41;277:5;242:41;:::i;:::-;202:86;;;;:::o;313:352::-;;;443:3;436:4;428:6;424:17;420:27;410:2;;461:1;458;451:12;410:2;494:6;481:20;471:30;;521:18;513:6;510:30;507:2;;;553:1;550;543:12;507:2;587:4;579:6;575:17;563:29;;638:3;630:4;622:6;618:17;608:8;604:32;601:41;598:2;;;655:1;652;645:12;598:2;403:262;;;;;:::o;673:124::-;;750:6;737:20;728:29;;762:30;786:5;762:30;:::i;:::-;722:75;;;;:::o;804:128::-;;885:6;879:13;870:22;;897:30;921:5;897:30;:::i;:::-;864:68;;;;:::o;939:164::-;;1038:6;1032:13;1023:22;;1050:48;1092:5;1050:48;:::i;:::-;1017:86;;;;:::o;1110:130::-;;1190:6;1177:20;1168:29;;1202:33;1229:5;1202:33;:::i;:::-;1162:78;;;;:::o;1247:134::-;;1331:6;1325:13;1316:22;;1343:33;1370:5;1343:33;:::i;:::-;1310:71;;;;:::o;1388:241::-;;1492:2;1480:9;1471:7;1467:23;1463:32;1460:2;;;1508:1;1505;1498:12;1460:2;1543:1;1560:53;1605:7;1596:6;1585:9;1581:22;1560:53;:::i;:::-;1550:63;;1522:97;1454:175;;;;:::o;1636:479::-;;;;1768:2;1756:9;1747:7;1743:23;1739:32;1736:2;;;1784:1;1781;1774:12;1736:2;1819:1;1836:53;1881:7;1872:6;1861:9;1857:22;1836:53;:::i;:::-;1826:63;;1798:97;1926:2;1944:50;1986:7;1977:6;1966:9;1962:22;1944:50;:::i;:::-;1934:60;;1905:95;2031:2;2049:50;2091:7;2082:6;2071:9;2067:22;2049:50;:::i;:::-;2039:60;;2010:95;1730:385;;;;;:::o;2122:397::-;;;2261:2;2249:9;2240:7;2236:23;2232:32;2229:2;;;2277:1;2274;2267:12;2229:2;2340:1;2329:9;2325:17;2312:31;2363:18;2355:6;2352:30;2349:2;;;2395:1;2392;2385:12;2349:2;2423:80;2495:7;2486:6;2475:9;2471:22;2423:80;:::i;:::-;2405:98;;;;2291:218;2223:296;;;;;:::o;2526:257::-;;2638:2;2626:9;2617:7;2613:23;2609:32;2606:2;;;2654:1;2651;2644:12;2606:2;2689:1;2706:61;2759:7;2750:6;2739:9;2735:22;2706:61;:::i;:::-;2696:71;;2668:105;2600:183;;;;:::o;2790:293::-;;2920:2;2908:9;2899:7;2895:23;2891:32;2888:2;;;2936:1;2933;2926:12;2888:2;2971:1;2988:79;3059:7;3050:6;3039:9;3035:22;2988:79;:::i;:::-;2978:89;;2950:123;2882:201;;;;:::o;3090:241::-;;3194:2;3182:9;3173:7;3169:23;3165:32;3162:2;;;3210:1;3207;3200:12;3162:2;3245:1;3262:53;3307:7;3298:6;3287:9;3283:22;3262:53;:::i;:::-;3252:63;;3224:97;3156:175;;;;:::o;3338:263::-;;3453:2;3441:9;3432:7;3428:23;3424:32;3421:2;;;3469:1;3466;3459:12;3421:2;3504:1;3521:64;3577:7;3568:6;3557:9;3553:22;3521:64;:::i;:::-;3511:74;;3483:108;3415:186;;;;:::o;3608:366::-;;;3729:2;3717:9;3708:7;3704:23;3700:32;3697:2;;;3745:1;3742;3735:12;3697:2;3780:1;3797:53;3842:7;3833:6;3822:9;3818:22;3797:53;:::i;:::-;3787:63;;3759:97;3887:2;3905:53;3950:7;3941:6;3930:9;3926:22;3905:53;:::i;:::-;3895:63;;3866:98;3691:283;;;;;:::o;3981:382::-;;;4110:2;4098:9;4089:7;4085:23;4081:32;4078:2;;;4126:1;4123;4116:12;4078:2;4161:1;4178:53;4223:7;4214:6;4203:9;4199:22;4178:53;:::i;:::-;4168:63;;4140:97;4268:2;4286:61;4339:7;4330:6;4319:9;4315:22;4286:61;:::i;:::-;4276:71;;4247:106;4072:291;;;;;:::o;4370:743::-;;;;;;4542:3;4530:9;4521:7;4517:23;4513:33;4510:2;;;4559:1;4556;4549:12;4510:2;4594:1;4611:53;4656:7;4647:6;4636:9;4632:22;4611:53;:::i;:::-;4601:63;;4573:97;4701:2;4719:53;4764:7;4755:6;4744:9;4740:22;4719:53;:::i;:::-;4709:63;;4680:98;4809:2;4827:53;4872:7;4863:6;4852:9;4848:22;4827:53;:::i;:::-;4817:63;;4788:98;4917:2;4935:53;4980:7;4971:6;4960:9;4956:22;4935:53;:::i;:::-;4925:63;;4896:98;5025:3;5044:53;5089:7;5080:6;5069:9;5065:22;5044:53;:::i;:::-;5034:63;;5004:99;4504:609;;;;;;;;:::o;5120:491::-;;;;5258:2;5246:9;5237:7;5233:23;5229:32;5226:2;;;5274:1;5271;5264:12;5226:2;5309:1;5326:53;5371:7;5362:6;5351:9;5347:22;5326:53;:::i;:::-;5316:63;;5288:97;5416:2;5434:53;5479:7;5470:6;5459:9;5455:22;5434:53;:::i;:::-;5424:63;;5395:98;5524:2;5542:53;5587:7;5578:6;5567:9;5563:22;5542:53;:::i;:::-;5532:63;;5503:98;5220:391;;;;;:::o;5618:366::-;;;5739:2;5727:9;5718:7;5714:23;5710:32;5707:2;;;5755:1;5752;5745:12;5707:2;5790:1;5807:53;5852:7;5843:6;5832:9;5828:22;5807:53;:::i;:::-;5797:63;;5769:97;5897:2;5915:53;5960:7;5951:6;5940:9;5936:22;5915:53;:::i;:::-;5905:63;;5876:98;5701:283;;;;;:::o;5992:203::-;;6094:61;6151:3;6143:6;6094:61;:::i;:::-;6184:4;6179:3;6175:14;6161:28;;6087:108;;;;:::o;6204:173::-;;6291:46;6333:3;6325:6;6291:46;:::i;:::-;6366:4;6361:3;6357:14;6343:28;;6284:93;;;;:::o;6385:113::-;6468:24;6486:5;6468:24;:::i;:::-;6463:3;6456:37;6450:48;;:::o;6544:765::-;;6704:69;6767:5;6704:69;:::i;:::-;6786:86;6865:6;6860:3;6786:86;:::i;:::-;6779:93;;6893:71;6958:5;6893:71;:::i;:::-;6984:7;7012:1;6997:290;7022:6;7019:1;7016:13;6997:290;;;7089:6;7083:13;7110:78;7184:3;7169:13;7110:78;:::i;:::-;7103:85;;7205:75;7273:6;7205:75;:::i;:::-;7195:85;;7054:233;7044:1;7041;7037:9;7032:14;;6997:290;;;7001:14;7300:3;7293:10;;6683:626;;;;;;;:::o;7348:690::-;;7493:54;7541:5;7493:54;:::i;:::-;7560:86;7639:6;7634:3;7560:86;:::i;:::-;7553:93;;7667:56;7717:5;7667:56;:::i;:::-;7743:7;7771:1;7756:260;7781:6;7778:1;7775:13;7756:260;;;7848:6;7842:13;7869:63;7928:3;7913:13;7869:63;:::i;:::-;7862:70;;7949:60;8002:6;7949:60;:::i;:::-;7939:70;;7813:203;7803:1;7800;7796:9;7791:14;;7756:260;;;7760:14;8029:3;8022:10;;7472:566;;;;;;;:::o;8046:356::-;;8174:38;8206:5;8174:38;:::i;:::-;8224:88;8305:6;8300:3;8224:88;:::i;:::-;8217:95;;8317:52;8362:6;8357:3;8350:4;8343:5;8339:16;8317:52;:::i;:::-;8390:6;8385:3;8381:16;8374:23;;8154:248;;;;;:::o;8409:146::-;8497:52;8543:5;8497:52;:::i;:::-;8492:3;8485:65;8479:76;;:::o;8562:156::-;8660:52;8706:5;8660:52;:::i;:::-;8655:3;8648:65;8642:76;;:::o;8726:321::-;;8886:67;8950:2;8945:3;8886:67;:::i;:::-;8879:74;;8986:23;8982:1;8977:3;8973:11;8966:44;9038:2;9033:3;9029:12;9022:19;;8872:175;;;:::o;9056:319::-;;9216:67;9280:2;9275:3;9216:67;:::i;:::-;9209:74;;9316:21;9312:1;9307:3;9303:11;9296:42;9366:2;9361:3;9357:12;9350:19;;9202:173;;;:::o;9384:328::-;;9544:67;9608:2;9603:3;9544:67;:::i;:::-;9537:74;;9644:30;9640:1;9635:3;9631:11;9624:51;9703:2;9698:3;9694:12;9687:19;;9530:182;;;:::o;9721:370::-;;9881:67;9945:2;9940:3;9881:67;:::i;:::-;9874:74;;9981:34;9977:1;9972:3;9968:11;9961:55;10050:3;10045:2;10040:3;10036:12;10029:25;10082:2;10077:3;10073:12;10066:19;;9867:224;;;:::o;10100:321::-;;10260:67;10324:2;10319:3;10260:67;:::i;:::-;10253:74;;10360:23;10356:1;10351:3;10347:11;10340:44;10412:2;10407:3;10403:12;10396:19;;10246:175;;;:::o;10430:328::-;;10590:67;10654:2;10649:3;10590:67;:::i;:::-;10583:74;;10690:30;10686:1;10681:3;10677:11;10670:51;10749:2;10744:3;10740:12;10733:19;;10576:182;;;:::o;10767:324::-;;10927:67;10991:2;10986:3;10927:67;:::i;:::-;10920:74;;11027:26;11023:1;11018:3;11014:11;11007:47;11082:2;11077:3;11073:12;11066:19;;10913:178;;;:::o;11100:370::-;;11260:67;11324:2;11319:3;11260:67;:::i;:::-;11253:74;;11360:34;11356:1;11351:3;11347:11;11340:55;11429:3;11424:2;11419:3;11415:12;11408:25;11461:2;11456:3;11452:12;11445:19;;11246:224;;;:::o;11479:332::-;;11639:67;11703:2;11698:3;11639:67;:::i;:::-;11632:74;;11739:34;11735:1;11730:3;11726:11;11719:55;11802:2;11797:3;11793:12;11786:19;;11625:186;;;:::o;11820:332::-;;11980:67;12044:2;12039:3;11980:67;:::i;:::-;11973:74;;12080:34;12076:1;12071:3;12067:11;12060:55;12143:2;12138:3;12134:12;12127:19;;11966:186;;;:::o;12161:327::-;;12321:67;12385:2;12380:3;12321:67;:::i;:::-;12314:74;;12421:29;12417:1;12412:3;12408:11;12401:50;12479:2;12474:3;12470:12;12463:19;;12307:181;;;:::o;12497:331::-;;12657:67;12721:2;12716:3;12657:67;:::i;:::-;12650:74;;12757:33;12753:1;12748:3;12744:11;12737:54;12819:2;12814:3;12810:12;12803:19;;12643:185;;;:::o;12837:324::-;;12997:67;13061:2;13056:3;12997:67;:::i;:::-;12990:74;;13097:26;13093:1;13088:3;13084:11;13077:47;13152:2;13147:3;13143:12;13136:19;;12983:178;;;:::o;13228:656::-;13373:4;13368:3;13364:14;13468:4;13461:5;13457:16;13451:23;13480:63;13537:4;13532:3;13528:14;13514:12;13480:63;:::i;:::-;13393:156;13632:4;13625:5;13621:16;13615:23;13644:61;13699:4;13694:3;13690:14;13676:12;13644:61;:::i;:::-;13559:152;13790:4;13783:5;13779:16;13773:23;13802:61;13857:4;13852:3;13848:14;13834:12;13802:61;:::i;:::-;13721:148;13346:538;;;:::o;13891:103::-;13964:24;13982:5;13964:24;:::i;:::-;13959:3;13952:37;13946:48;;:::o;14001:113::-;14084:24;14102:5;14084:24;:::i;:::-;14079:3;14072:37;14066:48;;:::o;14121:126::-;14204:37;14235:5;14204:37;:::i;:::-;14199:3;14192:50;14186:61;;:::o;14254:103::-;14327:24;14345:5;14327:24;:::i;:::-;14322:3;14315:37;14309:48;;:::o;14364:113::-;14447:24;14465:5;14447:24;:::i;:::-;14442:3;14435:37;14429:48;;:::o;14484:100::-;14555:23;14572:5;14555:23;:::i;:::-;14550:3;14543:36;14537:47;;:::o;14591:110::-;14672:23;14689:5;14672:23;:::i;:::-;14667:3;14660:36;14654:47;;:::o;14708:271::-;;14861:93;14950:3;14941:6;14861:93;:::i;:::-;14854:100;;14971:3;14964:10;;14842:137;;;;:::o;14986:222::-;;15113:2;15102:9;15098:18;15090:26;;15127:71;15195:1;15184:9;15180:17;15171:6;15127:71;:::i;:::-;15084:124;;;;:::o;15215:333::-;;15370:2;15359:9;15355:18;15347:26;;15384:71;15452:1;15441:9;15437:17;15428:6;15384:71;:::i;:::-;15466:72;15534:2;15523:9;15519:18;15510:6;15466:72;:::i;:::-;15341:207;;;;;:::o;15555:659::-;;15825:2;15814:9;15810:18;15802:26;;15875:9;15869:4;15865:20;15861:1;15850:9;15846:17;15839:47;15900:123;16018:4;16009:6;15900:123;:::i;:::-;15892:131;;16071:9;16065:4;16061:20;16056:2;16045:9;16041:18;16034:48;16096:108;16199:4;16190:6;16096:108;:::i;:::-;16088:116;;15796:418;;;;;:::o;16221:252::-;;16363:2;16352:9;16348:18;16340:26;;16377:86;16460:1;16449:9;16445:17;16436:6;16377:86;:::i;:::-;16334:139;;;;:::o;16480:416::-;;16680:2;16669:9;16665:18;16657:26;;16730:9;16724:4;16720:20;16716:1;16705:9;16701:17;16694:47;16755:131;16881:4;16755:131;:::i;:::-;16747:139;;16651:245;;;:::o;16903:416::-;;17103:2;17092:9;17088:18;17080:26;;17153:9;17147:4;17143:20;17139:1;17128:9;17124:17;17117:47;17178:131;17304:4;17178:131;:::i;:::-;17170:139;;17074:245;;;:::o;17326:416::-;;17526:2;17515:9;17511:18;17503:26;;17576:9;17570:4;17566:20;17562:1;17551:9;17547:17;17540:47;17601:131;17727:4;17601:131;:::i;:::-;17593:139;;17497:245;;;:::o;17749:416::-;;17949:2;17938:9;17934:18;17926:26;;17999:9;17993:4;17989:20;17985:1;17974:9;17970:17;17963:47;18024:131;18150:4;18024:131;:::i;:::-;18016:139;;17920:245;;;:::o;18172:416::-;;18372:2;18361:9;18357:18;18349:26;;18422:9;18416:4;18412:20;18408:1;18397:9;18393:17;18386:47;18447:131;18573:4;18447:131;:::i;:::-;18439:139;;18343:245;;;:::o;18595:416::-;;18795:2;18784:9;18780:18;18772:26;;18845:9;18839:4;18835:20;18831:1;18820:9;18816:17;18809:47;18870:131;18996:4;18870:131;:::i;:::-;18862:139;;18766:245;;;:::o;19018:416::-;;19218:2;19207:9;19203:18;19195:26;;19268:9;19262:4;19258:20;19254:1;19243:9;19239:17;19232:47;19293:131;19419:4;19293:131;:::i;:::-;19285:139;;19189:245;;;:::o;19441:416::-;;19641:2;19630:9;19626:18;19618:26;;19691:9;19685:4;19681:20;19677:1;19666:9;19662:17;19655:47;19716:131;19842:4;19716:131;:::i;:::-;19708:139;;19612:245;;;:::o;19864:416::-;;20064:2;20053:9;20049:18;20041:26;;20114:9;20108:4;20104:20;20100:1;20089:9;20085:17;20078:47;20139:131;20265:4;20139:131;:::i;:::-;20131:139;;20035:245;;;:::o;20287:416::-;;20487:2;20476:9;20472:18;20464:26;;20537:9;20531:4;20527:20;20523:1;20512:9;20508:17;20501:47;20562:131;20688:4;20562:131;:::i;:::-;20554:139;;20458:245;;;:::o;20710:416::-;;20910:2;20899:9;20895:18;20887:26;;20960:9;20954:4;20950:20;20946:1;20935:9;20931:17;20924:47;20985:131;21111:4;20985:131;:::i;:::-;20977:139;;20881:245;;;:::o;21133:416::-;;21333:2;21322:9;21318:18;21310:26;;21383:9;21377:4;21373:20;21369:1;21358:9;21354:17;21347:47;21408:131;21534:4;21408:131;:::i;:::-;21400:139;;21304:245;;;:::o;21556:416::-;;21756:2;21745:9;21741:18;21733:26;;21806:9;21800:4;21796:20;21792:1;21781:9;21777:17;21770:47;21831:131;21957:4;21831:131;:::i;:::-;21823:139;;21727:245;;;:::o;21979:326::-;;22158:2;22147:9;22143:18;22135:26;;22172:123;22292:1;22281:9;22277:17;22268:6;22172:123;:::i;:::-;22129:176;;;;:::o;22312:436::-;;22491:2;22480:9;22476:18;22468:26;;22505:71;22573:1;22562:9;22558:17;22549:6;22505:71;:::i;:::-;22587:70;22653:2;22642:9;22638:18;22629:6;22587:70;:::i;:::-;22668;22734:2;22723:9;22719:18;22710:6;22668:70;:::i;:::-;22462:286;;;;;;:::o;22755:222::-;;22882:2;22871:9;22867:18;22859:26;;22896:71;22964:1;22953:9;22949:17;22940:6;22896:71;:::i;:::-;22853:124;;;;:::o;22984:333::-;;23139:2;23128:9;23124:18;23116:26;;23153:71;23221:1;23210:9;23206:17;23197:6;23153:71;:::i;:::-;23235:72;23303:2;23292:9;23288:18;23279:6;23235:72;:::i;:::-;23110:207;;;;;:::o;23324:440::-;;23505:2;23494:9;23490:18;23482:26;;23519:69;23585:1;23574:9;23570:17;23561:6;23519:69;:::i;:::-;23599:72;23667:2;23656:9;23652:18;23643:6;23599:72;:::i;:::-;23682;23750:2;23739:9;23735:18;23726:6;23682:72;:::i;:::-;23476:288;;;;;;:::o;23771:166::-;;23872:3;23864:11;;23910:4;23905:3;23901:14;23893:22;;23858:79;;;:::o;23944:151::-;;24030:3;24022:11;;24068:4;24063:3;24059:14;24051:22;;24016:79;;;:::o;24102:152::-;;24226:5;24220:12;24210:22;;24191:63;;;:::o;24261:137::-;;24370:5;24364:12;24354:22;;24335:63;;;:::o;24405:121::-;;24498:5;24492:12;24482:22;;24463:63;;;:::o;24533:123::-;;24646:4;24641:3;24637:14;24629:22;;24623:33;;;:::o;24663:108::-;;24761:4;24756:3;24752:14;24744:22;;24738:33;;;:::o;24779:178::-;;24909:6;24904:3;24897:19;24946:4;24941:3;24937:14;24922:29;;24890:67;;;;:::o;24966:178::-;;25096:6;25091:3;25084:19;25133:4;25128:3;25124:14;25109:29;;25077:67;;;;:::o;25153:144::-;;25288:3;25273:18;;25266:31;;;;:::o;25306:163::-;;25421:6;25416:3;25409:19;25458:4;25453:3;25449:14;25434:29;;25402:67;;;;:::o;25477:91::-;;25539:24;25557:5;25539:24;:::i;:::-;25528:35;;25522:46;;;:::o;25575:99::-;;25645:24;25663:5;25645:24;:::i;:::-;25634:35;;25628:46;;;:::o;25681:85::-;;25754:5;25747:13;25740:21;25729:32;;25723:43;;;:::o;25773:106::-;;25850:24;25868:5;25850:24;:::i;:::-;25839:35;;25833:46;;;:::o;25886:113::-;;25959:34;25952:5;25948:46;25937:57;;25931:68;;;:::o;26006:121::-;;26079:42;26072:5;26068:54;26057:65;;26051:76;;;:::o;26134:72::-;;26196:5;26185:16;;26179:27;;;:::o;26213:96::-;;26285:18;26278:5;26274:30;26263:41;;26257:52;;;:::o;26316:151::-;;26410:52;26456:5;26410:52;:::i;:::-;26397:65;;26391:76;;;:::o;26474:123::-;;26568:24;26586:5;26568:24;:::i;:::-;26555:37;;26549:48;;;:::o;26604:108::-;;26683:24;26701:5;26683:24;:::i;:::-;26670:37;;26664:48;;;:::o;26720:268::-;26785:1;26792:101;26806:6;26803:1;26800:13;26792:101;;;26882:1;26877:3;26873:11;26867:18;26863:1;26858:3;26854:11;26847:39;26828:2;26825:1;26821:10;26816:15;;26792:101;;;26908:6;26905:1;26902:13;26899:2;;;26973:1;26964:6;26959:3;26955:16;26948:27;26899:2;26769:219;;;;:::o;26996:117::-;27065:24;27083:5;27065:24;:::i;:::-;27058:5;27055:35;27045:2;;27104:1;27101;27094:12;27045:2;27039:74;:::o;27120:133::-;27197:32;27223:5;27197:32;:::i;:::-;27190:5;27187:43;27177:2;;27244:1;27241;27234:12;27177:2;27171:82;:::o;27260:111::-;27326:21;27341:5;27326:21;:::i;:::-;27319:5;27316:32;27306:2;;27362:1;27359;27352:12;27306:2;27300:71;:::o;27378:147::-;27462:39;27495:5;27462:39;:::i;:::-;27455:5;27452:50;27442:2;;27516:1;27513;27506:12;27442:2;27436:89;:::o;27532:117::-;27601:24;27619:5;27601:24;:::i;:::-;27594:5;27591:35;27581:2;;27640:1;27637;27630:12;27581:2;27575:74;:::o
Swarm Source
ipfs://5b2776e192b3bfeb55fc7505d3973c0560e6b18c19e8fdc1fb5ad83356fbbff3
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.