Contract Overview
Balance:
0 AVAX
AVAX Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xdf8b9945e479b8eb2ad1cbbdc70580b11afa2d293879833e663d22c7730a3ab4 | 0x60806040 | 20722002 | 170 days 11 hrs ago | 0xdd5cf30f56c37d3243a23543dc5bd5ee576970e2 | IN | Create: LockerV2 | 0 AVAX | 0.140095489275 |
[ Download CSV Export ]
Contract Name:
LockerV2
Compiler Version
v0.8.7+commit.e28d00a7
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "SafeERC20.sol"; import "ERC20.sol"; import "Initializable.sol"; import "OwnableUpgradeable.sol"; import "PausableUpgradeable.sol"; import "ERC20Upgradeable.sol"; import "IBaseRewardPoolLocker.sol"; import "ILocker.sol"; import "IBribeManager.sol"; import "IMasterChefVTX.sol"; /// @title Locker /// @author Vector Team contract LockerV2 is Initializable, ERC20Upgradeable, OwnableUpgradeable, PausableUpgradeable { using SafeERC20 for IERC20; address public masterchief; address public stakingToken; // staking token in masterchief address public previousLocker; uint256 public maxSlot; uint256 public totalUnlocking; // number of vtx in an unlocking slot uint256 public constant DENOMINATOR = 10000; address public bribeManager; IERC20 public VTX; IBaseRewardPoolLocker public rewarder; UnlockingStrategy[] public unlockingStrategies; struct UnlockingStrategy { uint256 unlockTime; // Time for full unlock uint256 forfeitPercent; // % of stake forfeited uint256 rewardPercent; // % of rewards uint256 instantUnstakePercent; // % to unstake immediately bool isLinear; // is linear unlock bool isActive; } struct UserUnlocking { uint256 startTime; uint256 endTime; uint256 amount; // total amount comitted to the unlock slot, never changes except when reseting slot uint256 unlockingStrategy; uint256 alreadyUnstaked; uint256 alreadyWithdrawn; // total amount already withdrawn from contract ( mainly for linear unlocks) } mapping(address => uint256) public userUnlocking; // vtx in an unlock slot mapping(address => UserUnlocking[]) public userUnlockings; mapping(address => uint256) private lastTimeRewardClaimed; mapping(address => bool) public migrated; mapping(address => bool) public transferWhitelist; event UnlockStarts( address indexed user, uint256 indexed timestamp, uint256 amount, uint256 strategyIndex ); event ResetSlot( address indexed user, uint256 indexed timestamp, uint256 amount, uint256 slotIndex ); event Unlock(address indexed user, uint256 indexed timestamp, uint256 amount); event NewDeposit(address indexed user, uint256 indexed timestamp, uint256 amount); event Claim(address indexed user, uint256 indexed timestamp); function __LockerV2_init_( address _masterchief, uint256 _maxSlots, address _previousLocker, address _rewarder, address _stakingToken ) public initializer { __ERC20_init("Locked VTX", "LVTXv2"); __Ownable_init(); __Pausable_init(); require(_maxSlots > 0, "Max slots should not be null"); maxSlot = _maxSlots; masterchief = _masterchief; previousLocker = _previousLocker; stakingToken = _stakingToken; rewarder = IBaseRewardPoolLocker(_rewarder); VTX = IERC20(IMasterChefVTX(masterchief).vtx()); } modifier onlyMaster() { require(msg.sender == masterchief, "Only Masterchief"); _; } function setStrategyStatus(uint256 strategyIndex, bool status) external onlyOwner { unlockingStrategies[strategyIndex].isActive = status; } function setWhitelistForTransfer(address _for, bool status) external onlyOwner { transferWhitelist[_for] = status; } function setPreviousLocker(address _locker) external onlyOwner { previousLocker = _locker; } modifier assertEnoughVtxInContract() { _; require(VTX.balanceOf(address(this)) >= totalLocked(), "CRITICAL FAULT"); } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } function setBribeManager(address _address) external onlyOwner { bribeManager = _address; } function getAllUserUnlocking(address _user) external view returns (UserUnlocking[] memory slots) { uint256 length = getUserSlotLength(_user); slots = new UserUnlocking[](length); for (uint256 i; i < length; i++) { slots[i] = userUnlockings[_user][i]; } } // total Vtx held in contract function totalLocked() public view returns (uint256) { return totalSupply() + totalUnlocking; } function stakeInMasterChief() external onlyOwner { IERC20(stakingToken).approve(masterchief, IERC20(stakingToken).balanceOf(address(this))); IMasterChefVTX(masterchief).deposit( stakingToken, IERC20(stakingToken).balanceOf(address(this)) ); } function _queueRewards(address token, uint256 amount) internal { IERC20(token).approve(address(rewarder), amount); rewarder.queueNewRewards(amount, token); } function _harvestVtx() internal whenNotPaused { (uint256 pendingVtx, , , ) = IMasterChefVTX(masterchief).pendingTokens( stakingToken, address(this), address(0) ); IMasterChefVTX(masterchief).deposit(stakingToken, 0); _queueRewards(address(VTX), pendingVtx); } modifier harvestVtx() { _harvestVtx(); _; } // @notice Harvest pending VTX for this contract from the masterchief // Queue Vtx in the locker rewarder function harvest() external { _harvestVtx(); } /// @notice Change the max number of unlocking slots /// @param _maxDeposits the new max number function setMaxSlots(uint256 _maxDeposits) external onlyOwner { require(_maxDeposits > maxSlot, "Cannot decrease slot number"); maxSlot = _maxDeposits; } function addNewStrategy( uint256 _lockTime, uint256 _rewardPercent, uint256 _forfeitPercent, uint256 _instantUnstakePercent, bool _isLinear ) external onlyOwner { require(_rewardPercent <= DENOMINATOR, "Invalid reward percent"); require(_forfeitPercent + _instantUnstakePercent <= DENOMINATOR, "Invalid inputs"); unlockingStrategies.push( UnlockingStrategy({ unlockTime: _lockTime, forfeitPercent: _forfeitPercent, rewardPercent: _rewardPercent, instantUnstakePercent: _instantUnstakePercent, isLinear: _isLinear, isActive: true }) ); } /// @notice Get the n'th user slot info /// @param _user the user /// @param n the index of the deposit slot function getUserNthSlot(address _user, uint256 n) external view returns ( uint256 startTime, uint256 endTime, uint256 amount, uint256 unlockingStrategy, uint256 alreadyUnstaked, uint256 alreadyWithdrawn ) { UserUnlocking storage slot = userUnlockings[_user][n]; startTime = slot.startTime; endTime = slot.endTime; amount = slot.amount; unlockingStrategy = slot.unlockingStrategy; alreadyUnstaked = slot.alreadyUnstaked; alreadyWithdrawn = slot.alreadyWithdrawn; } /// @notice Get the number of user deposits /// @param _user the user /// @return nbDeposits the user number of deposit function getUserSlotLength(address _user) public view returns (uint256) { return userUnlockings[_user].length; } /// @notice Get the total VTX held by contract for user /// @param _user the user /// @return the total number of VTX deposited function getUserTotalDeposit(address _user) public view returns (uint256) { return balanceOf(_user) + userUnlocking[_user]; } // @notice deposit VTX in the contract // @param _amount the amount of VTX to deposit function deposit(uint256 _amount) external whenNotPaused harvestVtx assertEnoughVtxInContract { _deposit(msg.sender, msg.sender, _amount); } // @notice deposit VTX in the contract // @param _amount the amount of VTX to deposit // @param _for the address to deposit for // @dev the tokens will be taken from msg.sender function depositFor(address _for, uint256 _amount) external whenNotPaused harvestVtx assertEnoughVtxInContract { _deposit(msg.sender, _for, _amount); } function _deposit( address spender, address _for, uint256 _amount ) internal { VTX.safeTransferFrom(spender, address(this), _amount); rewarder.stakeFor(_for, _amount); _mint(_for, _amount); emit NewDeposit(_for, block.timestamp, _amount); } function resetSlot(address _for, uint256 slotIndex) internal { require(slotIndex < getUserSlotLength(_for), "Slot doesn't exist"); UserUnlocking storage slot = userUnlockings[_for][slotIndex]; UnlockingStrategy storage strategy = unlockingStrategies[slot.unlockingStrategy]; require( strategy.instantUnstakePercent == 0 || slot.alreadyWithdrawn == slot.amount, "Cannot reset an unfinished slot with instant unlock" ); uint256 remaining = slot.amount - slot.alreadyWithdrawn; if (remaining > 0) { userUnlocking[_for] -= remaining; totalUnlocking -= remaining; _mint(_for, remaining); } rewarder.stakeFor(msg.sender, slot.alreadyUnstaked - slot.alreadyWithdrawn); emit ResetSlot(_for, block.timestamp, slot.amount, slotIndex); slot.amount = 0; } // @notice for frontend function cancelUnlock(uint256 slotIndex) external whenNotPaused harvestVtx assertEnoughVtxInContract { startUnlock(1, 0, slotIndex); } // @notice for frontend function addToUnlock(uint256 amount, uint256 slotIndex) external whenNotPaused harvestVtx assertEnoughVtxInContract { uint256 userDepositLength = getUserSlotLength(msg.sender); require((slotIndex < userDepositLength), "Not in the range of allowed slots"); UserUnlocking storage info = userUnlockings[msg.sender][slotIndex]; startUnlock(info.unlockingStrategy, info.amount + amount, slotIndex); } // @notice starts an unlock slot // @notice this function can also be used to reset or change a slot // @param strategyIndex The choosen unlock strategy // @param amount the VTX amount for the slot // @param slotIndex the index of the slot to use function startUnlock( uint256 strategyIndex, uint256 amount, uint256 slotIndex ) public whenNotPaused harvestVtx assertEnoughVtxInContract { uint256 userDepositLength = getUserSlotLength(msg.sender); require( (slotIndex <= userDepositLength) && (slotIndex < maxSlot), "Not in the range of allowed slots" ); if (userDepositLength > slotIndex && userUnlockings[msg.sender][slotIndex].amount != 0) { resetSlot(msg.sender, slotIndex); } require(amount <= balanceOf(msg.sender), "Not enough locked VTX to start unlock"); require(strategyIndex != 0, "Strategy reserved for migration"); UnlockingStrategy storage strategy = unlockingStrategies[strategyIndex]; require(strategy.isActive, "Strategy not active"); _burn(msg.sender, amount); uint256 amountToUnlock = (strategy.instantUnstakePercent * amount) / DENOMINATOR; VTX.safeTransfer(msg.sender, amountToUnlock); uint256 amountToForfeit = (strategy.forfeitPercent * amount) / DENOMINATOR; _approveTokenIfNeeded(address(VTX), address(rewarder), amountToForfeit); IBaseRewardPoolLocker(rewarder).donateRewards(amountToForfeit, address(VTX)); uint256 forfeitedOrUnlocked = amountToUnlock + amountToForfeit; uint256 amountToUnstakeForRewards = ((DENOMINATOR - strategy.rewardPercent) * (amount - forfeitedOrUnlocked)) / DENOMINATOR; rewarder.withdrawFor( msg.sender, amountToUnstakeForRewards + forfeitedOrUnlocked, getUserRewardPercentage(msg.sender), true ); userUnlocking[msg.sender] += amount - forfeitedOrUnlocked; totalUnlocking += amount - forfeitedOrUnlocked; require( IBribeManager(bribeManager).userTotalVote(msg.sender) <= balanceOf(msg.sender), "Too much vote cast" ); if (slotIndex < userDepositLength) { userUnlockings[msg.sender][slotIndex] = UserUnlocking({ startTime: block.timestamp, endTime: block.timestamp + strategy.unlockTime, unlockingStrategy: strategyIndex, amount: amount - forfeitedOrUnlocked, alreadyUnstaked: amountToUnstakeForRewards, alreadyWithdrawn: 0 }); } else { userUnlockings[msg.sender].push( UserUnlocking({ startTime: block.timestamp, endTime: block.timestamp + strategy.unlockTime, unlockingStrategy: strategyIndex, amount: amount - forfeitedOrUnlocked, alreadyUnstaked: amountToUnstakeForRewards, alreadyWithdrawn: 0 }) ); } emit UnlockStarts(msg.sender, block.timestamp, amount, strategyIndex); } // @notice unlock a finished slot // @param slotIndex the index of the slot to unlock function unlock(uint256 slotIndex) external whenNotPaused harvestVtx assertEnoughVtxInContract { UserUnlocking storage slot = userUnlockings[msg.sender][slotIndex]; require(slot.amount > 0, "Inactive slot"); uint256 remaining = slot.amount - slot.alreadyWithdrawn; require(remaining > 0, "Already fully withdrawn"); // should never happen UnlockingStrategy storage strategy = unlockingStrategies[slot.unlockingStrategy]; uint256 amountToUnstake; uint256 amountToWithdraw; if (slot.endTime <= block.timestamp) { amountToUnstake = slot.amount - slot.alreadyUnstaked; amountToWithdraw = slot.amount - slot.alreadyWithdrawn; } else { require(strategy.isLinear, "Nothing to unlock"); uint256 totalTime = slot.endTime - slot.startTime; uint256 passedTime = block.timestamp - slot.startTime; uint256 ratio = (passedTime * DENOMINATOR) / totalTime; if (ratio > DENOMINATOR) { ratio = DENOMINATOR; } uint256 linearAmount = (slot.amount * ratio) / DENOMINATOR; if (linearAmount > slot.alreadyWithdrawn) { amountToWithdraw = linearAmount - slot.alreadyWithdrawn; } amountToUnstake = (amountToWithdraw * unlockingStrategies[slot.unlockingStrategy].rewardPercent) / DENOMINATOR; } userUnlocking[msg.sender] -= amountToWithdraw; totalUnlocking -= amountToWithdraw; VTX.safeTransfer(msg.sender, amountToWithdraw); rewarder.withdrawFor( msg.sender, amountToUnstake, getUserRewardPercentage(msg.sender), true ); slot.alreadyWithdrawn += amountToWithdraw; slot.alreadyUnstaked += amountToUnstake; emit Unlock(msg.sender, block.timestamp, slot.amount); if (slot.alreadyWithdrawn == slot.amount) { resetSlot(msg.sender, slotIndex); } } // @notice compute the percentage of rewards owed to the user // this function should always return 10000 if no slots is expired for the user function getUserRewardPercentage(address _user) public view returns (uint256 rewardPercentage) { // should return the percentage of rewards to send to the user ( in case of no interaction after a slot expire) // step 1 : get the total user staked uint256 totalUserStaked = rewarder.balanceOf(_user); if (totalUserStaked == 0) return 0; uint256 totalUserStakedWithFullReward = totalUserStaked; // setp 2 : search for finished user slot uint256 length = getUserSlotLength(_user); for (uint256 i; i < length; i++) { UserUnlocking storage slot = userUnlockings[_user][i]; if (slot.endTime < block.timestamp && slot.amount != 0) { uint256 slotStakedAmount = slot.amount - slot.alreadyUnstaked; if (slotStakedAmount > 0) { // compute the percentage for this particular slot uint256 lastInteractionTimestamp = lastTimeRewardClaimed[msg.sender] > slot.startTime ? lastTimeRewardClaimed[msg.sender] : slot.startTime; uint256 totalSlotTime = slot.endTime - lastInteractionTimestamp; uint256 passedTime = block.timestamp - lastInteractionTimestamp; uint256 slotRewardPercentage = (totalSlotTime * DENOMINATOR) / passedTime; // get the staked amount for this slot totalUserStakedWithFullReward -= slotStakedAmount; // get the percentage of all stake for this slot uint256 slotStakedPercentage = (slotStakedAmount * DENOMINATOR) / totalUserStaked; rewardPercentage += (slotStakedPercentage * slotRewardPercentage) / DENOMINATOR; } } } rewardPercentage += (totalUserStakedWithFullReward * DENOMINATOR) / totalUserStaked; } // @notice claim locker rewards // revert if a slot is expired & not withdrawn function claim() external whenNotPaused harvestVtx assertEnoughVtxInContract returns (address[] memory rewardTokens, uint256[] memory earnedRewards) { (rewardTokens, earnedRewards) = _claim(msg.sender); } // @notice claim locker rewards for another user // revert if a slot is expired & not withdrawn function claimFor(address _for) external whenNotPaused harvestVtx assertEnoughVtxInContract returns (address[] memory rewardTokens, uint256[] memory earnedRewards) { (rewardTokens, earnedRewards) = _claim(_for); } function _claim(address _for) internal whenNotPaused returns (address[] memory rewardTokens, uint256[] memory earnedRewards) { uint256 length = getUserSlotLength(_for); for (uint256 i; i < length; i++) { UserUnlocking memory slot = userUnlockings[_for][i]; if ( slot.endTime <= block.timestamp && slot.amount != 0 && unlockingStrategies[slot.unlockingStrategy].rewardPercent != 0 ) { revert("You need to withdraw all finished slots with rewards before claiming"); } // may be more gas efficient than a require in a loop } // maybe also only write an error code that will be translated in FE to reduce revert msg length (rewardTokens, earnedRewards) = rewarder.getReward(_for, DENOMINATOR); lastTimeRewardClaimed[_for] = block.timestamp; emit Claim(_for, block.timestamp); } function _migrate( address _from, address _to, bool[] calldata onlyDeposit ) internal { require(!migrated[_from], "Already migrated"); migrated[_from] = true; uint256 length = ILocker(previousLocker).getUserDepositLength(_from); require(onlyDeposit.length == length, "Incorrect input"); uint256 totalAmountToStake; uint256 totalAmountToRefund; UnlockingStrategy storage strategy = unlockingStrategies[0]; for (uint256 i; i < length; i++) { (, uint256 endTime, uint256 amount) = ILocker(previousLocker).getUserNthDeposit( _from, i ); uint256 amountToStake; if (endTime < block.timestamp) { totalAmountToRefund += amount; } else { amountToStake = (amount * strategy.rewardPercent) / DENOMINATOR; if (onlyDeposit[i]) { _mint(_to, amount); } else { userUnlocking[_to] += amount; totalUnlocking += amount; userUnlockings[_to].push( UserUnlocking({ startTime: block.timestamp, endTime: endTime, unlockingStrategy: 0, amount: amount, alreadyUnstaked: amount - amountToStake, alreadyWithdrawn: 0 }) ); } } totalAmountToStake += amountToStake; } uint256 actualLength = getUserSlotLength(_to); require(actualLength <= maxSlot, "Max slot reached"); rewarder.stakeFor(_to, totalAmountToStake); VTX.safeTransfer(_to, totalAmountToRefund); } // @notice migrate from the previous locker function migrate(address user, bool[] calldata onlyDeposit) external whenNotPaused onlyMaster { _migrate(user, user, onlyDeposit); } // @notice migrate from the previous locker function migrateFor( address _from, address _to, bool[] calldata onlyDeposit ) external whenNotPaused onlyMaster { _migrate(_from, _to, onlyDeposit); } /// @notice increase allowance to a contract to the maximum amount for a specific token if it is needed /// @param token the token to increase the allowance of /// @param _to the contract to increase the allowance /// @param _amount the amount of allowance that the contract needs function _approveTokenIfNeeded( address token, address _to, uint256 _amount ) private { if (IERC20(token).allowance(address(this), _to) < _amount) { IERC20(token).approve(_to, type(uint256).max); } } function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { if (!(from == address(0) || to == address(0))) { require(transferWhitelist[from] || transferWhitelist[to], "Not whitelisted"); rewarder.withdrawFor(from, amount, 0, false); rewarder.stakeFor(to, amount); } } function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual override { if (from != address(0)) { require( IBribeManager(bribeManager).userTotalVote(from) <= balanceOf(from), "Too much vote cast" ); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "IERC20.sol"; import "Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "IERC20.sol"; import "IERC20Metadata.sol"; import "Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "ContextUpgradeable.sol"; import "Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { __Context_init_unchained(); } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "ContextUpgradeable.sol"; import "Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Context_init_unchained(); __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "IERC20Upgradeable.sol"; import "IERC20MetadataUpgradeable.sol"; import "ContextUpgradeable.sol"; import "Initializable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} uint256[45] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; interface IBaseRewardPoolLocker { function DENOMINATOR() external view returns (uint256); function __BaseRewardPoolLocker_init_( address _stakingToken, address _rewardToken, address _operator, address _rewardManager ) external; function balanceOf(address _account) external view returns (uint256); function donateRewards(uint256 _amountReward, address _rewardToken) external returns (bool); function earned(address _account, address _rewardToken) external view returns (uint256); function getReward(address _account, uint256 rewardPercent) external returns (address[] memory rewardTokens, uint256[] memory earnedRewards); function getStakingToken() external view returns (address); function isRewardToken(address) external view returns (bool); function mainRewardToken() external view returns (address); function operator() external view returns (address); function owner() external view returns (address); function queueNewRewards(uint256 _amountReward, address _rewardToken) external returns (bool); function renounceOwnership() external; function rewardDecimals(address _rewardToken) external view returns (uint256); function rewardManager() external view returns (address); function rewardPerToken(address _rewardToken) external view returns (uint256); function rewardTokens(uint256) external view returns (address); function rewards(address) external view returns ( address rewardToken, uint256 rewardPerTokenStored, uint256 queuedRewards, uint256 historicalRewards ); function setOperator(address newOperator) external; function setRewardManager(address newOperator) external; function stakeFor(address _for, uint256 _amount) external returns (bool); function stakingDecimals() external view returns (uint256); function stakingToken() external view returns (address); function totalSupply() external view returns (uint256); function transferOwnership(address newOwner) external; function updateFor(address _account) external; function userRewardPerTokenPaid(address, address) external view returns (uint256); function userRewards(address, address) external view returns (uint256); function withdrawFor( address _for, uint256 _amount, uint256 rewardPercent, bool claim ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; interface ILocker { function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function balanceOf(address account) external view returns (uint256); function decimals() external view returns (uint8); function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); function depositFor( uint256 _amount, uint256 _index, address user, bool force ) external; function getUserDepositLength(address _user) external view returns (uint256 nbDeposits); function getUserNthDeposit(address _user, uint256 n) external view returns ( uint256 depositTime, uint256 endTime, uint256 amount ); function increaseAllowance(address spender, uint256 addedValue) external returns (bool); function lockTime() external view returns (uint256); function lockToken() external view returns (address); function masterchief() external view returns (address); function maxDeposits() external view returns (uint256); function name() external view returns (string memory); function owner() external view returns (address); function renounceOwnership() external; function setLockTime(uint256 _newvalue) external; function setMaxDeposits(uint256 _maxDeposits) external; function symbol() external view returns (string memory); function totalSupply() external view returns (uint256); function transfer(address recipient, uint256 amount) external view returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external view returns (bool); function transferOwnership(address newOwner) external; function userDeposits(address, uint256) external view returns ( uint256 depositTime, uint256 endTime, uint256 amount ); function withdrawFor( uint256 _amount, uint256 _index, address user ) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; interface IBribeManager { function __BribeManager_init( address _voter, address _veptp, address _mainStaking, address _locker ) external; function addPool( address _lp, address _rewarder, string calldata _name ) external; function avaxZapper() external view returns (address); function castVotes(bool swapForAvax) external returns (address[] memory finalRewardTokens, uint256[] memory finalFeeAmounts); function castVotesAndHarvestBribes(address[] calldata lps, bool swapForAvax) external returns (address[] memory finalRewardTokens, uint256[] memory finalFeeAmounts); function castVotesCooldown() external view returns (uint256); function clearPools() external; function getLvtxVoteForPools(address[] calldata lps) external view returns (uint256[] memory lvtxVotes); function getUserLocked(address _user) external view returns (uint256); function getUserVoteForPools(address[] calldata lps, address _user) external view returns (uint256[] memory votes); function getVoteForLp(address lp) external view returns (uint256); function getVoteForLps(address[] calldata lps) external view returns (uint256[] memory votes); function harvestAllBribes(address _for) external returns (address[] memory finalRewardTokens, uint256[] memory finalFeeAmounts); function harvestBribe(address[] calldata lps) external; function harvestBribeFor(address[] calldata lps, address _for) external; function harvestSinglePool(address[] calldata _lps) external; function isPoolActive(address pool) external view returns (bool); function lastCastTimer() external view returns (uint256); function locker() external view returns (address); function lpTokenLength() external view returns (uint256); function mainStaking() external view returns (address); function owner() external view returns (address); function poolInfos(address) external view returns ( address poolAddress, address rewarder, bool isActive, string memory name ); function poolTotalVote(address) external view returns (uint256); function pools(uint256) external view returns (address); function previewAvaxAmountForHarvest(address[] calldata _lps) external view returns (uint256); function previewBribes( address lp, address[] calldata inputRewardTokens, address _for ) external view returns (address[] memory rewardTokens, uint256[] memory amounts); function remainingVotes() external view returns (uint256); function removePool(uint256 _index) external; function renounceOwnership() external; function routePairAddresses(address) external view returns (address); function setAvaxZapper(address newZapper) external; function setPoolRewarder(address _pool, address _rewarder) external; function setVoter(address _voter) external; function totalVotes() external view returns (uint256); function totalVtxInVote() external view returns (uint256); function transferOwnership(address newOwner) external; function unvote(address _lp) external; function usedVote() external view returns (uint256); function userTotalVote(address) external view returns (uint256); function userVoteForPools(address, address) external view returns (uint256); function vePtp() external view returns (address); function veptpPerLockedVtx() external view returns (uint256); function vote(address[] calldata _lps, int256[] calldata _deltas) external; function voteAndCast( address[] calldata _lps, int256[] calldata _deltas, bool swapForAvax ) external; function voter() external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.7; interface IMasterChefVTX { function PoolManagers(address) external view returns (bool); function __MasterChefVTX_init( address _vtx, uint256 _vtxPerSec, uint256 _startTimestamp ) external; function add( uint256 _allocPoint, address _lpToken, address _rewarder, address _helper ) external; function addressToPoolInfo(address) external view returns ( address lpToken, uint256 allocPoint, uint256 lastRewardTimestamp, uint256 accVTXPerShare, address rewarder, address helper, address locker ); function allowEmergency() external; function authorizeForLock(address _address) external; function claimLegacyLock() external; function claimLegacyLockFor(address _for) external; function createRewarder(address _lpToken, address mainRewardToken) external returns (address); function deposit(address _lp, uint256 _amount) external; function depositFor( address _lp, uint256 _amount, address sender ) external; function depositInfo(address _lp, address _user) external view returns (uint256 availableAmount); function emergencyWithdraw(address _lp) external; function emergencyWithdrawWithReward(address _lp) external; function getPoolInfo(address token) external view returns ( uint256 emission, uint256 allocpoint, uint256 sizeOfPool, uint256 totalPoint ); function isAuthorizedForLock(address) external view returns (bool); function massUpdatePools() external; function migrateEmergency( address _from, address _to, bool[] calldata onlyDeposit ) external; function migrateToNewLocker(bool[] calldata onlyDeposit) external; function multiclaim(address[] calldata _lps, address user_address) external; function owner() external view returns (address); function pendingTokens( address _lp, address _user, address token ) external view returns ( uint256 pendingVTX, address bonusTokenAddress, string memory bonusTokenSymbol, uint256 pendingBonusToken ); function poolLength() external view returns (uint256); function realEmergencyWithdraw(address _lp) external; function registeredToken(uint256) external view returns (address); function renounceOwnership() external; function set( address _lp, uint256 _allocPoint, address _rewarder, address _locker, bool overwrite ) external; function setPoolHelper(address _lp, address _helper) external; function setPoolManagerStatus(address _address, bool _bool) external; function setVtxLocker(address newLocker) external; function startTimestamp() external view returns (uint256); function totalAllocPoint() external view returns (uint256); function transferOwnership(address newOwner) external; function updateEmissionRate(uint256 _vtxPerSec) external; function updatePool(address _lp) external; function vtx() external view returns (address); function vtxLocker() external view returns (address); function vtxPerSec() external view returns (uint256); function withdraw(address _lp, uint256 _amount) external; function withdrawFor( address _lp, uint256 _amount, address _sender ) external; }
{ "evmVersion": "istanbul", "optimizer": { "enabled": true, "runs": 999 }, "libraries": { "LockerV2.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NewDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"slotIndex","type":"uint256"}],"name":"ResetSlot","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Unlock","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strategyIndex","type":"uint256"}],"name":"UnlockStarts","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VTX","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_masterchief","type":"address"},{"internalType":"uint256","name":"_maxSlots","type":"uint256"},{"internalType":"address","name":"_previousLocker","type":"address"},{"internalType":"address","name":"_rewarder","type":"address"},{"internalType":"address","name":"_stakingToken","type":"address"}],"name":"__LockerV2_init_","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lockTime","type":"uint256"},{"internalType":"uint256","name":"_rewardPercent","type":"uint256"},{"internalType":"uint256","name":"_forfeitPercent","type":"uint256"},{"internalType":"uint256","name":"_instantUnstakePercent","type":"uint256"},{"internalType":"bool","name":"_isLinear","type":"bool"}],"name":"addNewStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slotIndex","type":"uint256"}],"name":"addToUnlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bribeManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slotIndex","type":"uint256"}],"name":"cancelUnlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"earnedRewards","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_for","type":"address"}],"name":"claimFor","outputs":[{"internalType":"address[]","name":"rewardTokens","type":"address[]"},{"internalType":"uint256[]","name":"earnedRewards","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_for","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"depositFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getAllUserUnlocking","outputs":[{"components":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockingStrategy","type":"uint256"},{"internalType":"uint256","name":"alreadyUnstaked","type":"uint256"},{"internalType":"uint256","name":"alreadyWithdrawn","type":"uint256"}],"internalType":"struct LockerV2.UserUnlocking[]","name":"slots","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"n","type":"uint256"}],"name":"getUserNthSlot","outputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockingStrategy","type":"uint256"},{"internalType":"uint256","name":"alreadyUnstaked","type":"uint256"},{"internalType":"uint256","name":"alreadyWithdrawn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserRewardPercentage","outputs":[{"internalType":"uint256","name":"rewardPercentage","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserSlotLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserTotalDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"masterchief","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSlot","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bool[]","name":"onlyDeposit","type":"bool[]"}],"name":"migrate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bool[]","name":"onlyDeposit","type":"bool[]"}],"name":"migrateFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"migrated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previousLocker","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewarder","outputs":[{"internalType":"contract IBaseRewardPoolLocker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"setBribeManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxDeposits","type":"uint256"}],"name":"setMaxSlots","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_locker","type":"address"}],"name":"setPreviousLocker","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"strategyIndex","type":"uint256"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setStrategyStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_for","type":"address"},{"internalType":"bool","name":"status","type":"bool"}],"name":"setWhitelistForTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakeInMasterChief","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"strategyIndex","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"slotIndex","type":"uint256"}],"name":"startUnlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUnlocking","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"transferWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"slotIndex","type":"uint256"}],"name":"unlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"unlockingStrategies","outputs":[{"internalType":"uint256","name":"unlockTime","type":"uint256"},{"internalType":"uint256","name":"forfeitPercent","type":"uint256"},{"internalType":"uint256","name":"rewardPercent","type":"uint256"},{"internalType":"uint256","name":"instantUnstakePercent","type":"uint256"},{"internalType":"bool","name":"isLinear","type":"bool"},{"internalType":"bool","name":"isActive","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"userUnlocking","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userUnlockings","outputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"unlockingStrategy","type":"uint256"},{"internalType":"uint256","name":"alreadyUnstaked","type":"uint256"},{"internalType":"uint256","name":"alreadyWithdrawn","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061584b80620000216000396000f3fe608060405234801561001057600080fd5b50600436106103785760003560e01c806383a24b4d116101d3578063c8691afe11610104578063dcc3e06e116100a2578063e2a578cd1161007c578063e2a578cd14610801578063e55c827314610814578063f2fde38b14610827578063f6b420ca1461083a57600080fd5b8063dcc3e06e146107a2578063dd62ed3e146107b5578063ddeae033146107ee57600080fd5b8063d0ea93d8116100de578063d0ea93d814610740578063d256c38c14610769578063d6b1c1f71461077c578063dc4794b21461078f57600080fd5b8063c8691afe14610711578063cc442e0f1461071a578063cf26b0c71461072d57600080fd5b8063a457c2d711610171578063a9059cbb1161014b578063a9059cbb146106c5578063a94c98ca146106d8578063af52247c146106eb578063b6b55f25146106fe57600080fd5b8063a457c2d71461068c578063a4c828dc1461069f578063a837fbd6146106b257600080fd5b80638da5cb5b116101ad5780638da5cb5b14610657578063918f86741461066857806395d89b41146106715780639e9284351461067957600080fd5b806383a24b4d146105ef5780638456cb591461060f578063873123091461061757600080fd5b80634e71d92d116102ad57806370a082311161024b57806372f702f31161022557806372f702f31461057b57806379c94062146105a65780637ffbe241146105b9578063819bfd9e146105dc57600080fd5b806370a0823114610537578063715018a61461056057806371f8da531461056857600080fd5b80635c1cb9b9116102875780635c1cb9b9146105085780635c975abb146105115780636198e3391461051c578063628601101461052f57600080fd5b80634e71d92d146104a657806356891412146104bc5780635a1ae6e6146104c457600080fd5b806323b872dd1161031a57806339509351116102f457806339509351146104605780633f4ba83a146104735780634641257d1461047b5780634ba0a5ee1461048357600080fd5b806323b872dd1461042b5780632f4f21e21461043e578063313ce5671461045157600080fd5b806318160ddd1161035657806318160ddd146103d3578063215b389a146103e55780632216dbf7146103f8578063225d95a71461041857600080fd5b806306fdde031461037d578063095ea7b31461039b57806309b0499d146103be575b600080fd5b61038561084d565b6040516103929190615616565b60405180910390f35b6103ae6103a93660046151a6565b6108df565b6040519015158152602001610392565b6103d16103cc36600461507d565b6108f5565b005b6035545b604051908152602001610392565b6103d16103f33660046151d2565b6109ac565b6103d761040636600461500a565b60d26020526000908152604090205481565b6103d1610426366004615178565b610c41565b6103ae6104393660046150e2565b610cb4565b6103d161044c3660046151a6565b610d75565b60405160128152602001610392565b6103ae61046e3660046151a6565b610e94565b6103d1610ed0565b6103d1610f22565b6103ae61049136600461500a565b60d56020526000908152604090205460ff1681565b6104ae610f2a565b604051610392929190615527565b6103d7611055565b6104d76104d2366004615340565b611072565b60408051968752602087019590955293850192909252606084015215156080830152151560a082015260c001610392565b6103d760cd5481565b60975460ff166103ae565b6103d161052a366004615340565b6110bf565b6103d16115e0565b6103d761054536600461500a565b6001600160a01b031660009081526033602052604090205490565b6103d1611811565b6103d16105763660046154cc565b611863565b60ca5461058e906001600160a01b031681565b6040516001600160a01b039091168152602001610392565b6103d16105b4366004615340565b611a80565b6103ae6105c736600461500a565b60d66020526000908152604090205460ff1681565b6103d16105ea366004615340565b611b1e565b6106026105fd36600461500a565b611b81565b604051610392919061559e565b6103d1611ced565b61062a6106253660046151a6565b611d3d565b604080519687526020870195909552938501929092526060840152608083015260a082015260c001610392565b6065546001600160a01b031661058e565b6103d761271081565b610385611d91565b60c95461058e906001600160a01b031681565b6103ae61069a3660046151a6565b611da0565b6103d76106ad36600461500a565b611e51565b6103d16106c036600461500a565b611e85565b6103ae6106d33660046151a6565b611eef565b61062a6106e63660046151a6565b611efc565b6103d76106f936600461500a565b611f7f565b6103d161070c366004615340565b6121b2565b6103d760cc5481565b60cf5461058e906001600160a01b031681565b6103d161073b36600461500a565b61220b565b6103d761074e36600461500a565b6001600160a01b0316600090815260d3602052604090205490565b60cb5461058e906001600160a01b031681565b6103d161078a366004615123565b612275565b6103d161079d366004615472565b612326565b60d05461058e906001600160a01b031681565b6103d76107c3366004615044565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b6104ae6107fc36600461500a565b612b44565b60ce5461058e906001600160a01b031681565b6103d1610822366004615450565b612c70565b6103d161083536600461500a565b612d80565b6103d161084836600461542b565b612e4d565b60606036805461085c9061573a565b80601f01602080910402602001604051908101604052809291908181526020018280546108889061573a565b80156108d55780601f106108aa576101008083540402835291602001916108d5565b820191906000526020600020905b8154815290600101906020018083116108b857829003601f168201915b5050505050905090565b60006108ec338484612ed5565b50600192915050565b60975460ff16156109405760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064015b60405180910390fd5b60c9546001600160a01b0316331461099a5760405162461bcd60e51b815260206004820152601060248201527f4f6e6c79204d61737465726368696566000000000000000000000000000000006044820152606401610937565b6109a68484848461302e565b50505050565b600054610100900460ff166109c75760005460ff16156109cb565b303b155b610a3d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610937565b600054610100900460ff16158015610a5f576000805461ffff19166101011790555b610ad36040518060400160405280600a81526020017f4c6f636b656420565458000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f4c56545876320000000000000000000000000000000000000000000000000000815250613509565b610adb613586565b610ae3613601565b60008511610b335760405162461bcd60e51b815260206004820152601c60248201527f4d617820736c6f74732073686f756c64206e6f74206265206e756c6c000000006044820152606401610937565b60cc85905560c980546001600160a01b038089166001600160a01b0319928316811790935560cb805488831690841617905560ca805486831690841617905560d0805491871691909216179055604080517fb76ae05e000000000000000000000000000000000000000000000000000000008152905163b76ae05e91600480820192602092909190829003018186803b158015610bcf57600080fd5b505afa158015610be3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c079190615027565b60cf80546001600160a01b0319166001600160a01b03929092169190911790558015610c39576000805461ff00191690555b505050505050565b6065546001600160a01b03163314610c895760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b6001600160a01b0391909116600090815260d660205260409020805460ff1916911515919091179055565b6000610cc184848461367c565b6001600160a01b038416600090815260346020908152604080832033845290915290205482811015610d5b5760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610937565b610d688533858403612ed5565b60019150505b9392505050565b60975460ff1615610dbb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b610dc36138a4565b610dce338383613a35565b610dd6611055565b60cf546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e519190615359565b1015610e905760405162461bcd60e51b815260206004820152600e60248201526d10d492551250d05308119055531560921b6044820152606401610937565b5050565b3360008181526034602090815260408083206001600160a01b038716845290915281205490916108ec918590610ecb90869061569e565b612ed5565b6065546001600160a01b03163314610f185760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b610f20613b1a565b565b610f206138a4565b606080610f3960975460ff1690565b15610f795760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b610f816138a4565b610f8a33613bb6565b9092509050610f97611055565b60cf546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610fda57600080fd5b505afa158015610fee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110129190615359565b10156110515760405162461bcd60e51b815260206004820152600e60248201526d10d492551250d05308119055531560921b6044820152606401610937565b9091565b600060cd5461106360355490565b61106d919061569e565b905090565b60d1818154811061108257600080fd5b6000918252602090912060059091020180546001820154600283015460038401546004909401549294509092909160ff8082169161010090041686565b60975460ff16156111055760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b61110d6138a4565b33600090815260d36020526040812080548390811061112e5761112e6157a6565b9060005260206000209060060201905060008160020154116111925760405162461bcd60e51b815260206004820152600d60248201527f496e61637469766520736c6f74000000000000000000000000000000000000006044820152606401610937565b6000816005015482600201546111a891906156f7565b9050600081116111fa5760405162461bcd60e51b815260206004820152601760248201527f416c72656164792066756c6c792077697468647261776e0000000000000000006044820152606401610937565b600060d1836003015481548110611213576112136157a6565b9060005260206000209060050201905060008042856001015411611262578460040154856002015461124591906156f7565b91508460050154856002015461125b91906156f7565b905061138e565b600483015460ff166112b65760405162461bcd60e51b815260206004820152601160248201527f4e6f7468696e6720746f20756e6c6f636b0000000000000000000000000000006044820152606401610937565b845460018601546000916112c9916156f7565b86549091506000906112db90426156f7565b90506000826112ec612710846156d8565b6112f691906156b6565b905061271081111561130757506127105b6000612710828a6002015461131c91906156d8565b61132691906156b6565b9050886005015481111561134657600589015461134390826156f7565b94505b61271060d18a6003015481548110611360576113606157a6565b9060005260206000209060050201600201548661137d91906156d8565b61138791906156b6565b9550505050505b33600090815260d26020526040812080548392906113ad9084906156f7565b925050819055508060cd60008282546113c691906156f7565b909155505060cf546113e2906001600160a01b03163383613e9a565b60d0546001600160a01b0316634a95116233846113fe82611f7f565b6040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260016064820152608401602060405180830381600087803b15801561145357600080fd5b505af1158015611467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148b9190615323565b50808560050160008282546114a0919061569e565b92505081905550818560040160008282546114bb919061569e565b90915550506002850154604051908152429033907ff7870c5b224cbc19873599e46ccfc7103934650509b1af0c3ce90138377c20049060200160405180910390a3846002015485600501541415611516576115163387613f2b565b5050505050611523611055565b60cf546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561156657600080fd5b505afa15801561157a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159e9190615359565b10156115dd5760405162461bcd60e51b815260206004820152600e60248201526d10d492551250d05308119055531560921b6044820152606401610937565b50565b6065546001600160a01b031633146116285760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b60ca5460c9546040516370a0823160e01b81523060048201526001600160a01b039283169263095ea7b392169083906370a082319060240160206040518083038186803b15801561167857600080fd5b505afa15801561168c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116b09190615359565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b1580156116f657600080fd5b505af115801561170a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172e9190615323565b5060c95460ca546040516370a0823160e01b81523060048201526001600160a01b03928316926347e7ef2492169081906370a082319060240160206040518083038186803b15801561177f57600080fd5b505afa158015611793573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b79190615359565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156117fd57600080fd5b505af11580156109a6573d6000803e3d6000fd5b6065546001600160a01b031633146118595760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b610f2060006141f9565b6065546001600160a01b031633146118ab5760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b6127108411156118fd5760405162461bcd60e51b815260206004820152601660248201527f496e76616c6964207265776172642070657263656e74000000000000000000006044820152606401610937565b61271061190a838561569e565b11156119585760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420696e707574730000000000000000000000000000000000006044820152606401610937565b6040805160c08101825295865260208601938452850193845260608501918252151560808501908152600160a0860181815260d180549283018155600052955160059091027f695fb3134ad82c3b8022bc5464edd0bcc9424ef672b52245dcb6ab2374327ce381019190915592517f695fb3134ad82c3b8022bc5464edd0bcc9424ef672b52245dcb6ab2374327ce484015592517f695fb3134ad82c3b8022bc5464edd0bcc9424ef672b52245dcb6ab2374327ce5830155517f695fb3134ad82c3b8022bc5464edd0bcc9424ef672b52245dcb6ab2374327ce682015590517f695fb3134ad82c3b8022bc5464edd0bcc9424ef672b52245dcb6ab2374327ce79091018054925115156101000261ff00199215159290921661ffff1990931692909217179055565b6065546001600160a01b03163314611ac85760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b60cc548111611b195760405162461bcd60e51b815260206004820152601b60248201527f43616e6e6f7420646563726561736520736c6f74206e756d62657200000000006044820152606401610937565b60cc55565b60975460ff1615611b645760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b611b6c6138a4565b611b796001600083612326565b611523611055565b60606000611ba4836001600160a01b0316600090815260d3602052604090205490565b90508067ffffffffffffffff811115611bbf57611bbf6157bc565b604051908082528060200260200182016040528015611c2957816020015b611c166040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b815260200190600190039081611bdd5790505b50915060005b81811015611ce6576001600160a01b038416600090815260d360205260409020805482908110611c6157611c616157a6565b90600052602060002090600602016040518060c00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481525050838281518110611cc857611cc86157a6565b60200260200101819052508080611cde90615775565b915050611c2f565b5050919050565b6065546001600160a01b03163314611d355760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b610f2061424b565b60d36020528160005260406000208181548110611d5957600080fd5b600091825260209091206006909102018054600182015460028301546003840154600485015460059095015493965091945092909186565b60606037805461085c9061573a565b3360009081526034602090815260408083206001600160a01b038616845290915281205482811015611e3a5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610937565b611e473385858403612ed5565b5060019392505050565b6001600160a01b038116600090815260d260209081526040808320546033909252822054611e7f919061569e565b92915050565b6065546001600160a01b03163314611ecd5760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b60cb80546001600160a01b0319166001600160a01b0392909216919091179055565b60006108ec33848461367c565b600080600080600080600060d360008a6001600160a01b03166001600160a01b031681526020019081526020016000208881548110611f3d57611f3d6157a6565b6000918252602090912060069091020180546001820154600283015460038401546004850154600590950154939e929d50909b50995091975095509350505050565b60d0546040516370a0823160e01b81526001600160a01b03838116600483015260009283929116906370a082319060240160206040518083038186803b158015611fc857600080fd5b505afa158015611fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120009190615359565b9050806120105750600092915050565b806000612032856001600160a01b0316600090815260d3602052604090205490565b905060005b81811015612187576001600160a01b038616600090815260d360205260408120805483908110612069576120696157a6565b9060005260206000209060060201905042816001015410801561208f5750600281015415155b15612174576000816004015482600201546120aa91906156f7565b9050801561217257815433600090815260d460205260408120549091106120d25782546120e3565b33600090815260d460205260409020545b905060008184600101546120f791906156f7565b9050600061210583426156f7565b9050600081612116612710856156d8565b61212091906156b6565b905061212c858a6156f7565b985060008a61213d612710886156d8565b61214791906156b6565b905061271061215683836156d8565b61216091906156b6565b61216a908d61569e565b9b5050505050505b505b508061217f81615775565b915050612037565b5082612195612710846156d8565b61219f91906156b6565b6121a9908561569e565b95945050505050565b60975460ff16156121f85760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b6122006138a4565b611b79333383613a35565b6065546001600160a01b031633146122535760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b60ce80546001600160a01b0319166001600160a01b0392909216919091179055565b60975460ff16156122bb5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b60c9546001600160a01b031633146123155760405162461bcd60e51b815260206004820152601060248201527f4f6e6c79204d61737465726368696566000000000000000000000000000000006044820152606401610937565b6123218384848461302e565b505050565b60975460ff161561236c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b6123746138a4565b33600090815260d36020526040902054808211801590612395575060cc5482105b6123eb5760405162461bcd60e51b815260206004820152602160248201527f4e6f7420696e207468652072616e6765206f6620616c6c6f77656420736c6f746044820152607360f81b6064820152608401610937565b818111801561242d575033600090815260d360205260409020805483908110612416576124166157a6565b906000526020600020906006020160020154600014155b1561243c5761243c3383613f2b565b336000908152603360205260409020548311156124c15760405162461bcd60e51b815260206004820152602560248201527f4e6f7420656e6f756768206c6f636b65642056545820746f207374617274207560448201527f6e6c6f636b0000000000000000000000000000000000000000000000000000006064820152608401610937565b8361250e5760405162461bcd60e51b815260206004820152601f60248201527f537472617465677920726573657276656420666f72206d6967726174696f6e006044820152606401610937565b600060d18581548110612523576125236157a6565b906000526020600020906005020190508060040160019054906101000a900460ff166125915760405162461bcd60e51b815260206004820152601360248201527f5374726174656779206e6f7420616374697665000000000000000000000000006044820152606401610937565b61259b33856142c6565b60006127108583600301546125b091906156d8565b6125ba91906156b6565b60cf549091506125d4906001600160a01b03163383613e9a565b60006127108684600101546125e991906156d8565b6125f391906156b6565b60cf5460d054919250612613916001600160a01b03918216911683614442565b60d05460cf546040517f5bc59ce7000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039182166024820152911690635bc59ce790604401602060405180830381600087803b15801561267c57600080fd5b505af1158015612690573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126b49190615323565b5060006126c1828461569e565b905060006127106126d2838a6156f7565b60028701546126e3906127106156f7565b6126ed91906156d8565b6126f791906156b6565b60d0549091506001600160a01b0316634a95116233612716858561569e565b61271f33611f7f565b6040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260016064820152608401602060405180830381600087803b15801561277457600080fd5b505af1158015612788573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ac9190615323565b506127b782896156f7565b33600090815260d26020526040812080549091906127d690849061569e565b909155506127e6905082896156f7565b60cd60008282546127f7919061569e565b90915550503360009081526033602052604090205460ce54604051637f0ea58960e11b81523360048201526001600160a01b039091169063fe1d4b129060240160206040518083038186803b15801561284f57600080fd5b505afa158015612863573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128879190615359565b11156128d55760405162461bcd60e51b815260206004820152601260248201527f546f6f206d75636820766f7465206361737400000000000000000000000000006044820152606401610937565b85871015612997576040518060c001604052804281526020018660000154426128fe919061569e565b815260200161290d848b6156f7565b815260208082018c905260408083018590526000606090930183905233835260d39091529020805489908110612945576129456157a6565b9060005260206000209060060201600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050155905050612a3f565b33600090815260d36020908152604091829020825160c081019093524280845288549193928301916129c89161569e565b81526020016129d7858c6156f7565b815260208082018d9052604080830186905260006060938401819052855460018181018855968252908390208551600690920201908155918401519482019490945592820151600284015581015160038301556080810151600483015560a001516005909101555b60408051898152602081018b9052429133917f9a398b809c9ca5dbc72899e94e5399292458136b18391a32adf6d254017211d7910160405180910390a3505050505050612a8a611055565b60cf546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015612acd57600080fd5b505afa158015612ae1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b059190615359565b10156123215760405162461bcd60e51b815260206004820152600e60248201526d10d492551250d05308119055531560921b6044820152606401610937565b606080612b5360975460ff1690565b15612b935760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b612b9b6138a4565b612ba483613bb6565b9092509050612bb1611055565b60cf546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015612bf457600080fd5b505afa158015612c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c2c9190615359565b1015612c6b5760405162461bcd60e51b815260206004820152600e60248201526d10d492551250d05308119055531560921b6044820152606401610937565b915091565b60975460ff1615612cb65760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b612cbe6138a4565b33600090815260d36020526040902054808210612d275760405162461bcd60e51b815260206004820152602160248201527f4e6f7420696e207468652072616e6765206f6620616c6c6f77656420736c6f746044820152607360f81b6064820152608401610937565b33600090815260d360205260408120805484908110612d4857612d486157a6565b90600052602060002090600602019050612d768160030154858360020154612d70919061569e565b85612326565b5050610dd6611055565b6065546001600160a01b03163314612dc85760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b6001600160a01b038116612e445760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610937565b6115dd816141f9565b6065546001600160a01b03163314612e955760405162461bcd60e51b815260206004820181905260248201526000805160206157f68339815191526044820152606401610937565b8060d18381548110612ea957612ea96157a6565b906000526020600020906005020160040160016101000a81548160ff0219169083151502179055505050565b6001600160a01b038316612f505760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610937565b6001600160a01b038216612fcc5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610937565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038416600090815260d5602052604090205460ff16156130975760405162461bcd60e51b815260206004820152601060248201527f416c7265616479206d69677261746564000000000000000000000000000000006044820152606401610937565b6001600160a01b03848116600081815260d56020526040808220805460ff1916600117905560cb5490517f87fa85f60000000000000000000000000000000000000000000000000000000081526004810193909352909216906387fa85f69060240160206040518083038186803b15801561311157600080fd5b505afa158015613125573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131499190615359565b905081811461319a5760405162461bcd60e51b815260206004820152600f60248201527f496e636f727265637420696e70757400000000000000000000000000000000006044820152606401610937565b600080600060d16000815481106131b3576131b36157a6565b9060005260206000209060050201905060005b848110156133f45760cb546040517f64e3826a0000000000000000000000000000000000000000000000000000000081526001600160a01b038b811660048301526024820184905260009283929116906364e3826a9060440160606040518083038186803b15801561323757600080fd5b505afa15801561324b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061326f919061549e565b925092505060004283101561328f57613288828761569e565b95506133d2565b6127108560020154836132a291906156d8565b6132ac91906156b6565b90508989858181106132c0576132c06157a6565b90506020020160208101906132d59190615306565b156132e9576132e48b83614567565b6133d2565b6001600160a01b038b16600090815260d260205260408120805484929061331190849061569e565b925050819055508160cd600082825461332a919061569e565b90915550506001600160a01b038b16600090815260d360209081526040808320815160c08101835242815292830187905290820185905260608201929092526080810161337784866156f7565b815260006020918201819052835460018181018655948252908290208351600690920201908155908201519281019290925560408101516002830155606081015160038301556080810151600483015560a001516005909101555b6133dc818861569e565b965050505080806133ec90615775565b9150506131c6565b506001600160a01b038716600090815260d3602052604090205460cc548111156134605760405162461bcd60e51b815260206004820152601060248201527f4d617820736c6f742072656163686564000000000000000000000000000000006044820152606401610937565b60d0546040516305dc812160e31b81526001600160a01b038a811660048301526024820187905290911690632ee4090890604401602060405180830381600087803b1580156134ae57600080fd5b505af11580156134c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134e69190615323565b5060cf546134fe906001600160a01b03168985613e9a565b505050505050505050565b600054610100900460ff166135745760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610937565b61357c61465a565b610e9082826146c5565b600054610100900460ff166135f15760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610937565b6135f961465a565b610f20614757565b600054610100900460ff1661366c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610937565b61367461465a565b610f206147cb565b6001600160a01b0383166136f85760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610937565b6001600160a01b0382166137745760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610937565b61377f838383614842565b6001600160a01b0383166000908152603360205260409020548181101561380e5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610937565b6001600160a01b0380851660009081526033602052604080822085850390559185168152908120805484929061384590849061569e565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161389191815260200190565b60405180910390a36109a68484846149d5565b60975460ff16156138ea5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b60c95460ca546040517fad05e6270000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015230602482015260006044820181905292919091169063ad05e6279060640160006040518083038186803b15801561395c57600080fd5b505afa158015613970573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526139989190810190615372565b505060c95460ca546040517f47e7ef240000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526000602482015293945016916347e7ef249150604401600060405180830381600087803b158015613a0657600080fd5b505af1158015613a1a573d6000803e3d6000fd5b505060cf546115dd92506001600160a01b0316905082614ac8565b60cf54613a4d906001600160a01b0316843084614bee565b60d0546040516305dc812160e31b81526001600160a01b0384811660048301526024820184905290911690632ee4090890604401602060405180830381600087803b158015613a9b57600080fd5b505af1158015613aaf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ad39190615323565b50613ade8282614567565b42826001600160a01b03167fa91e0c3165215fe453f5bf3de083d5fd6c4e62c491849155a042a647588c53a08360405161302191815260200190565b60975460ff16613b6c5760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610937565b6097805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b606080613bc560975460ff1690565b15613c055760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b6001600160a01b038316600090815260d36020526040812054905b81811015613da2576001600160a01b038516600090815260d360205260408120805483908110613c5257613c526157a6565b90600052602060002090600602016040518060c00160405290816000820154815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481525050905042816020015111158015613cc05750604081015115155b8015613cf5575060d1816060015181548110613cde57613cde6157a6565b906000526020600020906005020160020154600014155b15613d8f5760405162461bcd60e51b8152602060048201526044602482018190527f596f75206e65656420746f20776974686472617720616c6c2066696e69736865908201527f6420736c6f747320776974682072657761726473206265666f726520636c616960648201527f6d696e6700000000000000000000000000000000000000000000000000000000608482015260a401610937565b5080613d9a81615775565b915050613c20565b5060d0546040517ff474c8ce0000000000000000000000000000000000000000000000000000000081526001600160a01b03868116600483015261271060248301529091169063f474c8ce90604401600060405180830381600087803b158015613e0b57600080fd5b505af1158015613e1f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613e47919081019061523a565b6001600160a01b038616600081815260d4602052604080822042908190559051949750929550919290917f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d491a350915091565b6040516001600160a01b0383166024820152604481018290526123219084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152614c3f565b6001600160a01b038216600090815260d360205260409020548110613f925760405162461bcd60e51b815260206004820152601260248201527f536c6f7420646f65736e277420657869737400000000000000000000000000006044820152606401610937565b6001600160a01b038216600090815260d360205260408120805483908110613fbc57613fbc6157a6565b90600052602060002090600602019050600060d1826003015481548110613fe557613fe56157a6565b9060005260206000209060050201905080600301546000148061400f575081600201548260050154145b6140815760405162461bcd60e51b815260206004820152603360248201527f43616e6e6f7420726573657420616e20756e66696e697368656420736c6f742060448201527f7769746820696e7374616e7420756e6c6f636b000000000000000000000000006064820152608401610937565b60008260050154836002015461409791906156f7565b905080156140f0576001600160a01b038516600090815260d26020526040812080548392906140c79084906156f7565b925050819055508060cd60008282546140e091906156f7565b909155506140f090508582614567565b60d054600584015460048501546001600160a01b0390921691632ee4090891339161411b91906156f7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561416157600080fd5b505af1158015614175573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141999190615323565b5042856001600160a01b03167f18bb409513c8a4200071013ba207717a498fea554fe05c6f40a145866a4e820f8560020154876040516141e3929190918252602082015260400190565b60405180910390a3505060006002909101555050565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60975460ff16156142915760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610937565b6097805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613b993390565b6001600160a01b0382166143265760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610937565b61433282600083614842565b6001600160a01b038216600090815260336020526040902054818110156143c15760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610937565b6001600160a01b03831660009081526033602052604081208383039055603580548492906143f09084906156f7565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3612321836000846149d5565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03838116602483015282919085169063dd62ed3e9060440160206040518083038186803b1580156144a557600080fd5b505afa1580156144b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144dd9190615359565b10156123215760405163095ea7b360e01b81526001600160a01b038381166004830152600019602483015284169063095ea7b3906044015b602060405180830381600087803b15801561452f57600080fd5b505af1158015614543573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a69190615323565b6001600160a01b0382166145bd5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610937565b6145c960008383614842565b80603560008282546145db919061569e565b90915550506001600160a01b0382166000908152603360205260408120805483929061460890849061569e565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610e90600083836149d5565b600054610100900460ff16610f205760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610937565b600054610100900460ff166147305760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610937565b8151614743906036906020850190614eb3565b508051612321906037906020840190614eb3565b600054610100900460ff166147c25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610937565b610f20336141f9565b600054610100900460ff166148365760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608401610937565b6097805460ff19169055565b6001600160a01b038316158061485f57506001600160a01b038216155b612321576001600160a01b038316600090815260d6602052604090205460ff16806148a257506001600160a01b038216600090815260d6602052604090205460ff165b6148ee5760405162461bcd60e51b815260206004820152600f60248201527f4e6f742077686974656c697374656400000000000000000000000000000000006044820152606401610937565b60d0546040517f4a9511620000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260248201849052600060448301819052606483015290911690634a95116290608401602060405180830381600087803b15801561496357600080fd5b505af1158015614977573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061499b9190615323565b5060d0546040516305dc812160e31b81526001600160a01b0384811660048301526024820184905290911690632ee4090890604401614515565b6001600160a01b03831615612321576001600160a01b03831660009081526033602052604090205460ce54604051637f0ea58960e11b81526001600160a01b0386811660048301529091169063fe1d4b129060240160206040518083038186803b158015614a4257600080fd5b505afa158015614a56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614a7a9190615359565b11156123215760405162461bcd60e51b815260206004820152601260248201527f546f6f206d75636820766f7465206361737400000000000000000000000000006044820152606401610937565b60d05460405163095ea7b360e01b81526001600160a01b039182166004820152602481018390529083169063095ea7b390604401602060405180830381600087803b158015614b1657600080fd5b505af1158015614b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b4e9190615323565b5060d0546040517f8fcf4822000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b03848116602483015290911690638fcf482290604401602060405180830381600087803b158015614bb657600080fd5b505af1158015614bca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123219190615323565b6040516001600160a01b03808516602483015283166044820152606481018290526109a69085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401613edf565b6000614c94826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614d249092919063ffffffff16565b8051909150156123215780806020019051810190614cb29190615323565b6123215760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610937565b6060614d338484600085614d3b565b949350505050565b606082471015614db35760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610937565b843b614e015760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610937565b600080866001600160a01b03168587604051614e1d919061550b565b60006040518083038185875af1925050503d8060008114614e5a576040519150601f19603f3d011682016040523d82523d6000602084013e614e5f565b606091505b5091509150614e6f828286614e7a565b979650505050505050565b60608315614e89575081610d6e565b825115614e995782518084602001fd5b8160405162461bcd60e51b81526004016109379190615616565b828054614ebf9061573a565b90600052602060002090601f016020900481019282614ee15760008555614f27565b82601f10614efa57805160ff1916838001178555614f27565b82800160010185558215614f27579182015b82811115614f27578251825591602001919060010190614f0c565b50614f33929150614f37565b5090565b5b80821115614f335760008155600101614f38565b60008083601f840112614f5e57600080fd5b50813567ffffffffffffffff811115614f7657600080fd5b6020830191508360208260051b8501011115614f9157600080fd5b9250929050565b600082601f830112614fa957600080fd5b81516020614fbe614fb98361567a565b615649565b80838252828201915082860187848660051b8901011115614fde57600080fd5b60005b85811015614ffd57815184529284019290840190600101614fe1565b5090979650505050505050565b60006020828403121561501c57600080fd5b8135610d6e816157d2565b60006020828403121561503957600080fd5b8151610d6e816157d2565b6000806040838503121561505757600080fd5b8235615062816157d2565b91506020830135615072816157d2565b809150509250929050565b6000806000806060858703121561509357600080fd5b843561509e816157d2565b935060208501356150ae816157d2565b9250604085013567ffffffffffffffff8111156150ca57600080fd5b6150d687828801614f4c565b95989497509550505050565b6000806000606084860312156150f757600080fd5b8335615102816157d2565b92506020840135615112816157d2565b929592945050506040919091013590565b60008060006040848603121561513857600080fd5b8335615143816157d2565b9250602084013567ffffffffffffffff81111561515f57600080fd5b61516b86828701614f4c565b9497909650939450505050565b6000806040838503121561518b57600080fd5b8235615196816157d2565b91506020830135615072816157e7565b600080604083850312156151b957600080fd5b82356151c4816157d2565b946020939093013593505050565b600080600080600060a086880312156151ea57600080fd5b85356151f5816157d2565b945060208601359350604086013561520c816157d2565b9250606086013561521c816157d2565b9150608086013561522c816157d2565b809150509295509295909350565b6000806040838503121561524d57600080fd5b825167ffffffffffffffff8082111561526557600080fd5b818501915085601f83011261527957600080fd5b81516020615289614fb98361567a565b8083825282820191508286018a848660051b89010111156152a957600080fd5b600096505b848710156152d55780516152c1816157d2565b8352600196909601959183019183016152ae565b50918801519196509093505050808211156152ef57600080fd5b506152fc85828601614f98565b9150509250929050565b60006020828403121561531857600080fd5b8135610d6e816157e7565b60006020828403121561533557600080fd5b8151610d6e816157e7565b60006020828403121561535257600080fd5b5035919050565b60006020828403121561536b57600080fd5b5051919050565b6000806000806080858703121561538857600080fd5b84519350602085015161539a816157d2565b604086015190935067ffffffffffffffff808211156153b857600080fd5b818701915087601f8301126153cc57600080fd5b8151818111156153de576153de6157bc565b6153f1601f8201601f1916602001615649565b915080825288602082850101111561540857600080fd5b61541981602084016020860161570e565b50606096909601519497939650505050565b6000806040838503121561543e57600080fd5b823591506020830135615072816157e7565b6000806040838503121561546357600080fd5b50508035926020909101359150565b60008060006060848603121561548757600080fd5b505081359360208301359350604090920135919050565b6000806000606084860312156154b357600080fd5b8351925060208401519150604084015190509250925092565b600080600080600060a086880312156154e457600080fd5b85359450602086013593506040860135925060608601359150608086013561522c816157e7565b6000825161551d81846020870161570e565b9190910192915050565b604080825283519082018190526000906020906060840190828701845b828110156155695781516001600160a01b031684529284019290840190600101615544565b5050508381038285015284518082528583019183019060005b81811015614ffd57835183529284019291840191600101615582565b602080825282518282018190526000919060409081850190868401855b828110156156095781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c090930192908501906001016155bb565b5091979650505050505050565b602081526000825180602084015261563581604085016020870161570e565b601f01601f19169190910160400192915050565b604051601f8201601f1916810167ffffffffffffffff81118282101715615672576156726157bc565b604052919050565b600067ffffffffffffffff821115615694576156946157bc565b5060051b60200190565b600082198211156156b1576156b1615790565b500190565b6000826156d357634e487b7160e01b600052601260045260246000fd5b500490565b60008160001904831182151516156156f2576156f2615790565b500290565b60008282101561570957615709615790565b500390565b60005b83811015615729578181015183820152602001615711565b838111156109a65750506000910152565b600181811c9082168061574e57607f821691505b6020821081141561576f57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561578957615789615790565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146115dd57600080fd5b80151581146115dd57600080fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a264697066735822122090cc341419335ae3c5f301bebc431e3e08193cc24ddd46ca8bfcdb8306488a2b64736f6c63430008070033
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.