Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0x2c34752d8120a6e41c50b0fe56df0cb7c155756a5daa1a05e3fdb015f0463c76 | 28410216 | 376 days 5 hrs ago | 0x7add42d9c53df14c1bc2507034f63b0ac924345f | Contract Creation | 0 MATIC |
[ Download CSV Export ]
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x76ff85109C9236101961784D5F779e25Cec85C10
Contract Name:
Bribe
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "../../interface/IBribe.sol"; import "../../interface/IERC721.sol"; import "../../interface/IVoter.sol"; import "../../interface/IVe.sol"; import "./MultiRewardsPoolBase.sol"; /// @title Bribes pay out rewards for a given pool based on the votes /// that were received from the user (goes hand in hand with Gauges.vote()) contract Bribe is IBribe, MultiRewardsPoolBase { /// @dev Only voter can modify balances (since it only happens on vote()) address public immutable voter; address public immutable ve; // Assume that will be created from voter contract through factory constructor( address _voter, address[] memory _allowedRewardTokens ) MultiRewardsPoolBase(address(0), _voter, _allowedRewardTokens) { voter = _voter; ve = IVoter(_voter).ve(); } function getReward(uint tokenId, address[] memory tokens) external { require(IVe(ve).isApprovedOrOwner(msg.sender, tokenId), "Not token owner"); _getReward(_tokenIdToAddress(tokenId), tokens, msg.sender); } /// @dev Used by Voter to allow batched reward claims function getRewardForOwner(uint tokenId, address[] memory tokens) external override { require(msg.sender == voter, "Not voter"); address owner = IERC721(ve).ownerOf(tokenId); _getReward(_tokenIdToAddress(tokenId), tokens, owner); } /// @dev This is an external function, but internal notation is used /// since it can only be called "internally" from Gauges function _deposit(uint amount, uint tokenId) external override { require(msg.sender == voter, "Not voter"); require(amount > 0, "Zero amount"); address adr = _tokenIdToAddress(tokenId); _increaseBalance(adr, amount); emit Deposit(adr, amount); } function _withdraw(uint amount, uint tokenId) external override { require(msg.sender == voter, "Not voter"); require(amount > 0, "Zero amount"); address adr = _tokenIdToAddress(tokenId); _decreaseBalance(adr, amount); emit Withdraw(adr, amount); } /// @dev Used to notify a gauge/bribe of a given reward, /// this can create griefing attacks by extending rewards function notifyRewardAmount(address token, uint amount) external override { _notifyRewardAmount(token, amount); } // use tokenId instead of address for function tokenIdToAddress(uint tokenId) external pure returns (address) { return _tokenIdToAddress(tokenId); } function _tokenIdToAddress(uint tokenId) internal pure returns (address) { address adr = address(uint160(tokenId)); require(_addressToTokenId(adr) == tokenId, "Wrong convert"); return adr; } function addressToTokenId(address adr) external pure returns (uint) { return _addressToTokenId(adr); } function _addressToTokenId(address adr) internal pure returns (uint) { return uint(uint160(adr)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IBribe { function notifyRewardAmount(address token, uint amount) external; function _deposit(uint amount, uint tokenId) external; function _withdraw(uint amount, uint tokenId) external; function getRewardForOwner(uint tokenId, address[] memory tokens) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "./IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IVoter { function ve() external view returns (address); function attachTokenToGauge(uint _tokenId, address account) external; function detachTokenFromGauge(uint _tokenId, address account) external; function emitDeposit(uint _tokenId, address account, uint amount) external; function emitWithdraw(uint _tokenId, address account, uint amount) external; function distribute(address _gauge) external; function notifyRewardAmount(uint amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; interface IVe { enum DepositType { DEPOSIT_FOR_TYPE, CREATE_LOCK_TYPE, INCREASE_LOCK_AMOUNT, INCREASE_UNLOCK_TIME, MERGE_TYPE } struct Point { int128 bias; int128 slope; // # -dweight / dt uint ts; uint blk; // block } /* We cannot really do block numbers per se b/c slope is per time, not per block * and per block could be fairly bad b/c Ethereum changes blocktimes. * What we can do is to extrapolate ***At functions */ struct LockedBalance { int128 amount; uint end; } function token() external view returns (address); function balanceOfNFT(uint) external view returns (uint); function isApprovedOrOwner(address, uint) external view returns (bool); function createLockFor(uint, uint, address) external returns (uint); function userPointEpoch(uint tokenId) external view returns (uint); function epoch() external view returns (uint); function userPointHistory(uint tokenId, uint loc) external view returns (Point memory); function pointHistory(uint loc) external view returns (Point memory); function checkpoint() external; function depositFor(uint tokenId, uint value) external; function attachToken(uint tokenId) external; function detachToken(uint tokenId) external; function voting(uint tokenId) external; function abstain(uint tokenId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "../../interface/IERC20.sol"; import "../../interface/IMultiRewardsPool.sol"; import "../../lib/Math.sol"; import "../../lib/SafeERC20.sol"; import "../../lib/CheckpointLib.sol"; import "../Reentrancy.sol"; abstract contract MultiRewardsPoolBase is Reentrancy, IMultiRewardsPool { using SafeERC20 for IERC20; using CheckpointLib for mapping(uint => CheckpointLib.Checkpoint); /// @dev Operator can add/remove reward tokens address public operator; /// @dev The LP token that needs to be staked for rewards address public immutable override underlying; uint public override derivedSupply; mapping(address => uint) public override derivedBalances; /// @dev Rewards are released over 7 days uint internal constant DURATION = 7 days; uint internal constant PRECISION = 10 ** 18; uint internal constant MAX_REWARD_TOKENS = 10; /// Default snx staking contract implementation /// https://github.com/Synthetixio/synthetix/blob/develop/contracts/StakingRewards.sol /// @dev Reward rate with precision 1e18 mapping(address => uint) public rewardRate; mapping(address => uint) public periodFinish; mapping(address => uint) public lastUpdateTime; mapping(address => uint) public rewardPerTokenStored; mapping(address => mapping(address => uint)) public lastEarn; mapping(address => mapping(address => uint)) public userRewardPerTokenStored; uint public override totalSupply; mapping(address => uint) public override balanceOf; address[] public override rewardTokens; mapping(address => bool) public override isRewardToken; /// @notice A record of balance checkpoints for each account, by index mapping(address => mapping(uint => CheckpointLib.Checkpoint)) public checkpoints; /// @notice The number of checkpoints for each account mapping(address => uint) public numCheckpoints; /// @notice A record of balance checkpoints for each token, by index mapping(uint => CheckpointLib.Checkpoint) public supplyCheckpoints; /// @notice The number of checkpoints uint public supplyNumCheckpoints; /// @notice A record of balance checkpoints for each token, by index mapping(address => mapping(uint => CheckpointLib.Checkpoint)) public rewardPerTokenCheckpoints; /// @notice The number of checkpoints for each token mapping(address => uint) public rewardPerTokenNumCheckpoints; event Deposit(address indexed from, uint amount); event Withdraw(address indexed from, uint amount); event NotifyReward(address indexed from, address indexed reward, uint amount); event ClaimRewards(address indexed from, address indexed reward, uint amount, address recepient); constructor(address _stake, address _operator, address[] memory _allowedRewardTokens) { underlying = _stake; operator = _operator; for (uint i; i < _allowedRewardTokens.length; i++) { if (_allowedRewardTokens[i] != address(0)) { _registerRewardToken(_allowedRewardTokens[i]); } } } modifier onlyOperator() { require(msg.sender == operator, "Not operator"); _; } //************************************************************************** //************************ VIEWS ******************************************* //************************************************************************** function rewardTokensLength() external view override returns (uint) { return rewardTokens.length; } function rewardPerToken(address token) external view returns (uint) { return _rewardPerToken(token); } function _rewardPerToken(address token) internal view returns (uint) { if (derivedSupply == 0) { return rewardPerTokenStored[token]; } return rewardPerTokenStored[token] + ( (_lastTimeRewardApplicable(token) - Math.min(lastUpdateTime[token], periodFinish[token])) * rewardRate[token] / derivedSupply ); } function derivedBalance(address account) external view override returns (uint) { return _derivedBalance(account); } function left(address token) external view override returns (uint) { if (block.timestamp >= periodFinish[token]) return 0; uint _remaining = periodFinish[token] - block.timestamp; return _remaining * rewardRate[token] / PRECISION; } function earned(address token, address account) external view override returns (uint) { return _earned(token, account); } //************************************************************************** //************************ OPERATOR ACTIONS ******************************** //************************************************************************** function registerRewardToken(address token) external onlyOperator { _registerRewardToken(token); } function _registerRewardToken(address token) internal { require(rewardTokens.length < MAX_REWARD_TOKENS, "Too many reward tokens"); require(!isRewardToken[token], "Already registered"); isRewardToken[token] = true; rewardTokens.push(token); } function removeRewardToken(address token) external onlyOperator { require(periodFinish[token] < block.timestamp, "Rewards not ended"); require(isRewardToken[token], "Not reward token"); isRewardToken[token] = false; uint length = rewardTokens.length; require(length > 3, "First 3 tokens should not be removed"); // keep 3 tokens as guarantee against malicious actions // assume it will be DYST + pool tokens uint i = 3; bool found = false; for (; i < length; i++) { address t = rewardTokens[i]; if (t == token) { found = true; break; } } require(found, "First tokens forbidden to remove"); rewardTokens[i] = rewardTokens[length - 1]; rewardTokens.pop(); } //************************************************************************** //************************ USER ACTIONS ************************************ //************************************************************************** function _deposit(uint amount) internal virtual lock { require(amount > 0, "Zero amount"); _increaseBalance(msg.sender, amount); IERC20(underlying).safeTransferFrom(msg.sender, address(this), amount); emit Deposit(msg.sender, amount); } function _increaseBalance(address account, uint amount) internal virtual { _updateRewardForAllTokens(); totalSupply += amount; balanceOf[account] += amount; _updateDerivedBalanceAndWriteCheckpoints(account); } function _withdraw(uint amount) internal lock virtual { _decreaseBalance(msg.sender, amount); IERC20(underlying).safeTransfer(msg.sender, amount); emit Withdraw(msg.sender, amount); } function _decreaseBalance(address account, uint amount) internal virtual { _updateRewardForAllTokens(); totalSupply -= amount; balanceOf[account] -= amount; _updateDerivedBalanceAndWriteCheckpoints(account); } /// @dev Implement restriction checks! function _getReward(address account, address[] memory tokens, address recipient) internal lock virtual { for (uint i = 0; i < tokens.length; i++) { (rewardPerTokenStored[tokens[i]], lastUpdateTime[tokens[i]]) = _updateRewardPerToken(tokens[i], type(uint).max, true); uint _reward = _earned(tokens[i], account); lastEarn[tokens[i]][account] = block.timestamp; userRewardPerTokenStored[tokens[i]][account] = rewardPerTokenStored[tokens[i]]; if (_reward > 0) { IERC20(tokens[i]).safeTransfer(recipient, _reward); } emit ClaimRewards(msg.sender, tokens[i], _reward, recipient); } _updateDerivedBalanceAndWriteCheckpoints(account); } function _updateDerivedBalanceAndWriteCheckpoints(address account) internal { uint __derivedBalance = derivedBalances[account]; derivedSupply -= __derivedBalance; __derivedBalance = _derivedBalance(account); derivedBalances[account] = __derivedBalance; derivedSupply += __derivedBalance; _writeCheckpoint(account, __derivedBalance); _writeSupplyCheckpoint(); } //************************************************************************** //************************ REWARDS CALCULATIONS **************************** //************************************************************************** // earned is an estimation, it won't be exact till the supply > rewardPerToken calculations have run function _earned(address token, address account) internal view returns (uint) { // zero checkpoints means zero deposits if (numCheckpoints[account] == 0) { return 0; } // last claim rewards time uint _startTimestamp = Math.max(lastEarn[token][account], rewardPerTokenCheckpoints[token][0].timestamp); // find an index of the balance that the user had on the last claim uint _startIndex = _getPriorBalanceIndex(account, _startTimestamp); uint _endIndex = numCheckpoints[account] - 1; uint reward = 0; // calculate previous snapshots if exist if (_endIndex > 0) { for (uint i = _startIndex; i <= _endIndex - 1; i++) { CheckpointLib.Checkpoint memory cp0 = checkpoints[account][i]; CheckpointLib.Checkpoint memory cp1 = checkpoints[account][i + 1]; (uint _rewardPerTokenStored0,) = _getPriorRewardPerToken(token, cp0.timestamp); (uint _rewardPerTokenStored1,) = _getPriorRewardPerToken(token, cp1.timestamp); reward += cp0.value * (_rewardPerTokenStored1 - _rewardPerTokenStored0) / PRECISION; } } CheckpointLib.Checkpoint memory cp = checkpoints[account][_endIndex]; (uint _rewardPerTokenStored,) = _getPriorRewardPerToken(token, cp.timestamp); reward += cp.value * (_rewardPerToken(token) - Math.max(_rewardPerTokenStored, userRewardPerTokenStored[token][account])) / PRECISION; return reward; } function _derivedBalance(address account) internal virtual view returns (uint) { // supposed to be implemented in a parent contract return balanceOf[account]; } /// @dev Update stored rewardPerToken values without the last one snapshot /// If the contract will get "out of gas" error on users actions this will be helpful function batchUpdateRewardPerToken(address token, uint maxRuns) external { (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token, maxRuns, false); } function _updateRewardForAllTokens() internal { uint length = rewardTokens.length; for (uint i; i < length; i++) { address token = rewardTokens[i]; (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token, type(uint).max, true); } } /// @dev Should be called only with properly updated snapshots, or with actualLast=false function _updateRewardPerToken(address token, uint maxRuns, bool actualLast) internal returns (uint, uint) { uint _startTimestamp = lastUpdateTime[token]; uint reward = rewardPerTokenStored[token]; if (supplyNumCheckpoints == 0) { return (reward, _startTimestamp); } if (rewardRate[token] == 0) { return (reward, block.timestamp); } uint _startIndex = _getPriorSupplyIndex(_startTimestamp); uint _endIndex = Math.min(supplyNumCheckpoints - 1, maxRuns); if (_endIndex > 0) { for (uint i = _startIndex; i <= _endIndex - 1; i++) { CheckpointLib.Checkpoint memory sp0 = supplyCheckpoints[i]; if (sp0.value > 0) { CheckpointLib.Checkpoint memory sp1 = supplyCheckpoints[i + 1]; (uint _reward, uint _endTime) = _calcRewardPerToken( token, sp1.timestamp, sp0.timestamp, sp0.value, _startTimestamp ); reward += _reward; _writeRewardPerTokenCheckpoint(token, reward, _endTime); _startTimestamp = _endTime; } } } // need to override the last value with actual numbers only on deposit/withdraw/claim/notify actions if (actualLast) { CheckpointLib.Checkpoint memory sp = supplyCheckpoints[_endIndex]; if (sp.value > 0) { (uint _reward,) = _calcRewardPerToken(token, _lastTimeRewardApplicable(token), Math.max(sp.timestamp, _startTimestamp), sp.value, _startTimestamp); reward += _reward; _writeRewardPerTokenCheckpoint(token, reward, block.timestamp); _startTimestamp = block.timestamp; } } return (reward, _startTimestamp); } function _calcRewardPerToken( address token, uint lastSupplyTs1, uint lastSupplyTs0, uint supply, uint startTimestamp ) internal view returns (uint, uint) { uint endTime = Math.max(lastSupplyTs1, startTimestamp); uint _periodFinish = periodFinish[token]; return ( (Math.min(endTime, _periodFinish) - Math.min(Math.max(lastSupplyTs0, startTimestamp), _periodFinish)) * rewardRate[token] / supply , endTime); } /// @dev Returns the last time the reward was modified or periodFinish if the reward has ended function _lastTimeRewardApplicable(address token) internal view returns (uint) { return Math.min(block.timestamp, periodFinish[token]); } //************************************************************************** //************************ NOTIFY ****************************************** //************************************************************************** function _notifyRewardAmount(address token, uint amount) internal lock virtual { require(token != underlying, "Wrong token for rewards"); require(amount > 0, "Zero amount"); require(isRewardToken[token], "Token not allowed"); if (rewardRate[token] == 0) { _writeRewardPerTokenCheckpoint(token, 0, block.timestamp); } (rewardPerTokenStored[token], lastUpdateTime[token]) = _updateRewardPerToken(token, type(uint).max, true); if (block.timestamp >= periodFinish[token]) { IERC20(token).safeTransferFrom(msg.sender, address(this), amount); rewardRate[token] = amount * PRECISION / DURATION; } else { uint _remaining = periodFinish[token] - block.timestamp; uint _left = _remaining * rewardRate[token]; // not sure what the reason was in the original solidly implementation for this restriction // however, by design probably it is a good idea against human errors require(amount > _left / PRECISION, "Amount should be higher than remaining rewards"); IERC20(token).safeTransferFrom(msg.sender, address(this), amount); rewardRate[token] = (amount * PRECISION + _left) / DURATION; } periodFinish[token] = block.timestamp + DURATION; emit NotifyReward(msg.sender, token, amount); } //************************************************************************** //************************ CHECKPOINTS ************************************* //************************************************************************** function getPriorBalanceIndex(address account, uint timestamp) external view returns (uint) { return _getPriorBalanceIndex(account, timestamp); } /// @notice Determine the prior balance for an account as of a block number /// @dev Block number must be a finalized block or else this function will revert to prevent misinformation. /// @param account The address of the account to check /// @param timestamp The timestamp to get the balance at /// @return The balance the account had as of the given block function _getPriorBalanceIndex(address account, uint timestamp) internal view returns (uint) { uint nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; } return checkpoints[account].findLowerIndex(nCheckpoints, timestamp); } function getPriorSupplyIndex(uint timestamp) external view returns (uint) { return _getPriorSupplyIndex(timestamp); } function _getPriorSupplyIndex(uint timestamp) internal view returns (uint) { uint nCheckpoints = supplyNumCheckpoints; if (nCheckpoints == 0) { return 0; } return supplyCheckpoints.findLowerIndex(nCheckpoints, timestamp); } function getPriorRewardPerToken(address token, uint timestamp) external view returns (uint, uint) { return _getPriorRewardPerToken(token, timestamp); } function _getPriorRewardPerToken(address token, uint timestamp) internal view returns (uint, uint) { uint nCheckpoints = rewardPerTokenNumCheckpoints[token]; if (nCheckpoints == 0) { return (0, 0); } mapping(uint => CheckpointLib.Checkpoint) storage cps = rewardPerTokenCheckpoints[token]; uint lower = cps.findLowerIndex(nCheckpoints, timestamp); CheckpointLib.Checkpoint memory cp = cps[lower]; return (cp.value, cp.timestamp); } function _writeCheckpoint(address account, uint balance) internal { uint _timestamp = block.timestamp; uint _nCheckPoints = numCheckpoints[account]; if (_nCheckPoints > 0 && checkpoints[account][_nCheckPoints - 1].timestamp == _timestamp) { checkpoints[account][_nCheckPoints - 1].value = balance; } else { checkpoints[account][_nCheckPoints] = CheckpointLib.Checkpoint(_timestamp, balance); numCheckpoints[account] = _nCheckPoints + 1; } } function _writeRewardPerTokenCheckpoint(address token, uint reward, uint timestamp) internal { uint _nCheckPoints = rewardPerTokenNumCheckpoints[token]; if (_nCheckPoints > 0 && rewardPerTokenCheckpoints[token][_nCheckPoints - 1].timestamp == timestamp) { rewardPerTokenCheckpoints[token][_nCheckPoints - 1].value = reward; } else { rewardPerTokenCheckpoints[token][_nCheckPoints] = CheckpointLib.Checkpoint(timestamp, reward); rewardPerTokenNumCheckpoints[token] = _nCheckPoints + 1; } } function _writeSupplyCheckpoint() internal { uint _nCheckPoints = supplyNumCheckpoints; uint _timestamp = block.timestamp; if (_nCheckPoints > 0 && supplyCheckpoints[_nCheckPoints - 1].timestamp == _timestamp) { supplyCheckpoints[_nCheckPoints - 1].value = derivedSupply; } else { supplyCheckpoints[_nCheckPoints] = CheckpointLib.Checkpoint(_timestamp, derivedSupply); supplyNumCheckpoints = _nCheckPoints + 1; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; /** * @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 pragma solidity ^0.8.13; interface IMultiRewardsPool { function underlying() external view returns (address); function derivedSupply() external view returns (uint); function derivedBalances(address account) external view returns (uint); function totalSupply() external view returns (uint); function balanceOf(address account) external view returns (uint); function rewardTokens(uint id) external view returns (address); function isRewardToken(address token) external view returns (bool); function rewardTokensLength() external view returns (uint); function derivedBalance(address account) external view returns (uint); function left(address token) external view returns (uint); function earned(address token, address account) external view returns (uint); function registerRewardToken(address token) external; function removeRewardToken(address token) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; library Math { function max(uint a, uint b) internal pure returns (uint) { return a >= b ? a : b; } function min(uint a, uint b) internal pure returns (uint) { return a < b ? a : b; } function positiveInt128(int128 value) internal pure returns (int128) { return value < 0 ? int128(0) : value; } function closeTo(uint a, uint b, uint target) internal pure returns (bool) { if (a > b) { if (a - b <= target) { return true; } } else { if (b - a <= target) { return true; } } return false; } function sqrt(uint y) internal pure returns (uint z) { if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.13; import "../interface/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, uint value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint value ) internal { uint newAllowance = token.allowance(address(this), spender) + 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 pragma solidity ^0.8.13; library CheckpointLib { /// @notice A checkpoint for uint value struct Checkpoint { uint timestamp; uint value; } function findLowerIndex(mapping(uint => Checkpoint) storage checkpoints, uint size, uint timestamp) internal view returns (uint) { require(size != 0, "Empty checkpoints"); // First check most recent value if (checkpoints[size - 1].timestamp <= timestamp) { return (size - 1); } // Next check implicit zero value if (checkpoints[0].timestamp > timestamp) { return 0; } uint lower = 0; uint upper = size - 1; while (upper > lower) { // ceil, avoiding overflow uint center = upper - (upper - lower) / 2; Checkpoint memory cp = checkpoints[center]; if (cp.timestamp == timestamp) { return center; } else if (cp.timestamp < timestamp) { lower = center; } else { upper = center - 1; } } return lower; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; abstract contract Reentrancy { /// @dev simple re-entrancy check uint internal _unlocked = 1; modifier lock() { require(_unlocked == 1, "Reentrant call"); _unlocked = 2; _; _unlocked = 1; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.13; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call(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); } } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_voter","type":"address"},{"internalType":"address[]","name":"_allowedRewardTokens","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"recepient","type":"address"}],"name":"ClaimRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"reward","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NotifyReward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"_deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"_withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"adr","type":"address"}],"name":"addressToTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"maxRuns","type":"uint256"}],"name":"batchUpdateRewardPerToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"checkpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"derivedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"derivedBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"derivedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorBalanceIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorRewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"getPriorSupplyIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"getRewardForOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isRewardToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"lastEarn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"left","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"numCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"periodFinish","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"registerRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"removeRewardToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPerTokenCheckpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPerTokenNumCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardTokensLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"supplyCheckpoints","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supplyNumCheckpoints","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenIdToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ve","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60e060405260016000553480156200001657600080fd5b5060405162002db838038062002db88339810160408190526200003991620002cb565b60006080819052600180546001600160a01b0319166001600160a01b0385161790558282825b8151811015620000e25760006001600160a01b0316828281518110620000895762000089620003b4565b60200260200101516001600160a01b031614620000cd57620000cd828281518110620000b957620000b9620003b4565b60200260200101516200017a60201b60201c565b80620000d981620003ca565b9150506200005f565b50505050816001600160a01b031660a0816001600160a01b031681525050816001600160a01b0316631f8507166040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200013f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001659190620003f2565b6001600160a01b031660c05250620004179050565b600c54600a11620001d25760405162461bcd60e51b815260206004820152601660248201527f546f6f206d616e792072657761726420746f6b656e730000000000000000000060448201526064015b60405180910390fd5b6001600160a01b0381166000908152600d602052604090205460ff1615620002325760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e481c9959da5cdd195c995960721b6044820152606401620001c9565b6001600160a01b03166000818152600d60205260408120805460ff19166001908117909155600c805491820181559091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319169091179055565b80516001600160a01b0381168114620002b057600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215620002df57600080fd5b620002ea8362000298565b602084810151919350906001600160401b03808211156200030a57600080fd5b818601915086601f8301126200031f57600080fd5b815181811115620003345762000334620002b5565b8060051b604051601f19603f830116810181811085821117156200035c576200035c620002b5565b6040529182528482019250838101850191898311156200037b57600080fd5b938501935b82851015620003a457620003948562000298565b8452938501939285019262000380565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b600060018201620003eb57634e487b7160e01b600052601160045260246000fd5b5060010190565b6000602082840312156200040557600080fd5b620004108262000298565b9392505050565b60805160a05160c051612947620004716000396000818161032501528181610be10152610dd00152600081816103df01528181610ac401528181610b8b0152610d0501526000818161045f015261178201526129476000f3fe608060405234801561001057600080fd5b50600436106102485760003560e01c80637bb7bed11161013b578063d35e2544116100b8578063f12297771161007c578063f122977714610631578063f320772314610644578063f5f8d36514610657578063f7412baf1461066a578063fd3140981461069157600080fd5b8063d35e2544146105d9578063d7da4bb0146105ec578063da09d19d146105f5578063e46dbc9814610615578063e8111a121461062857600080fd5b8063a7852afa116100ff578063a7852afa14610558578063aa4796521461056b578063b5fd73f81461058b578063b66503cf146105be578063bf199e62146105d157600080fd5b80637bb7bed1146104d457806399bcc052146104e75780639ce43f90146104fa5780639e2bf22c1461051a578063a495e5b51461052d57600080fd5b80633d509c97116101c957806368fcee1a1161018d57806368fcee1a146104475780636f307dc31461045a5780636fcfff451461048157806370a08231146104a157806376f4be36146104c157600080fd5b80633d509c97146103c557806346c96aac146103da578063570ca7351461040157806363fb415b146104145780636511bf2e1461043457600080fd5b80631f850716116102105780631f85071614610320578063211dc32d14610347578063221ca18c1461035a5780632ce9aead1461037a5780633ca068b61461039a57600080fd5b806301316ddf1461024d57806308bb76a5146102995780630cdfebfa146102c4578063115c6f39146102f657806318160ddd14610317575b600080fd5b61027f61025b3660046125a0565b60126020908152600092835260408084209091529082529020805460019091015482565b604080519283526020830191909152015b60405180910390f35b6102ac6102a73660046125cc565b6106a4565b6040516001600160a01b039091168152602001610290565b61027f6102d23660046125a0565b600e6020908152600092835260408084209091529082529020805460019091015482565b6103096103043660046125a0565b6106b5565b604051908152602001610290565b610309600a5481565b6102ac7f000000000000000000000000000000000000000000000000000000000000000081565b6103096103553660046125e5565b6106c8565b61030961036836600461261e565b60046020526000908152604090205481565b61030961038836600461261e565b60066020526000908152604090205481565b6103096103a83660046125e5565b600960209081526000928352604080842090915290825290205481565b6103d86103d336600461261e565b6106d4565b005b6102ac7f000000000000000000000000000000000000000000000000000000000000000081565b6001546102ac906001600160a01b031681565b61030961042236600461261e565b60036020526000908152604090205481565b61030961044236600461261e565b6109b4565b6103d86104553660046125a0565b6109c5565b6102ac7f000000000000000000000000000000000000000000000000000000000000000081565b61030961048f36600461261e565b600f6020526000908152604090205481565b6103096104af36600461261e565b600b6020526000908152604090205481565b6103096104cf3660046125cc565b6109ff565b6102ac6104e23660046125cc565b610a0a565b6103096104f536600461261e565b610a34565b61030961050836600461261e565b60076020526000908152604090205481565b6103d861052836600461263b565b610ab9565b61030961053b3660046125e5565b600860209081526000928352604080842090915290825290205481565b6103d8610566366004612673565b610b80565b61030961057936600461261e565b60136020526000908152604090205481565b6105ae61059936600461261e565b600d6020526000908152604090205460ff1681565b6040519015158152602001610290565b6103d86105cc3660046125a0565b610c6e565b600c54610309565b6103096105e736600461261e565b610c7c565b61030960025481565b61030961060336600461261e565b60056020526000908152604090205481565b6103d861062336600461261e565b610c9a565b61030960115481565b61030961063f36600461261e565b610cef565b6103d861065236600461263b565b610cfa565b6103d8610665366004612673565b610db4565b61027f6106783660046125cc565b6010602052600090815260409020805460019091015482565b61027f61069f3660046125a0565b610e94565b60006106af82610ead565b92915050565b60006106c18383610ef8565b9392505050565b60006106c18383610f4d565b6001546001600160a01b031633146107225760405162461bcd60e51b815260206004820152600c60248201526b2737ba1037b832b930ba37b960a11b60448201526064015b60405180910390fd5b6001600160a01b038116600090815260056020526040902054421161077d5760405162461bcd60e51b815260206004820152601160248201527014995dd85c991cc81b9bdd08195b991959607a1b6044820152606401610719565b6001600160a01b0381166000908152600d602052604090205460ff166107d85760405162461bcd60e51b815260206004820152601060248201526f2737ba103932bbb0b932103a37b5b2b760811b6044820152606401610719565b6001600160a01b0381166000908152600d60205260409020805460ff19169055600c54600381116108575760405162461bcd60e51b8152602060048201526024808201527f4669727374203320746f6b656e732073686f756c64206e6f742062652072656d6044820152631bdd995960e21b6064820152608401610719565b600360005b828210156108b7576000600c838154811061087957610879612744565b6000918252602090912001546001600160a01b039081169150851681036108a45760019150506108b7565b50816108af81612770565b92505061085c565b806109045760405162461bcd60e51b815260206004820181905260248201527f466972737420746f6b656e7320666f7262696464656e20746f2072656d6f76656044820152606401610719565b600c610911600185612789565b8154811061092157610921612744565b600091825260209091200154600c80546001600160a01b03909216918490811061094d5761094d612744565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600c80548061098c5761098c6127a0565b600082815260209020810160001990810180546001600160a01b031916905501905550505050565b60006001600160a01b0382166106af565b6109d1828260006111ce565b6001600160a01b03909316600090815260076020908152604080832060069092529091209390935590915550565b60006106af826113be565b600c8181548110610a1a57600080fd5b6000918252602090912001546001600160a01b0316905081565b6001600160a01b0381166000908152600560205260408120544210610a5b57506000919050565b6001600160a01b038216600090815260056020526040812054610a7f904290612789565b6001600160a01b038416600090815260046020526040902054909150670de0b6b3a764000090610aaf90836127b6565b6106c191906127d5565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b015760405162461bcd60e51b8152600401610719906127f7565b60008211610b215760405162461bcd60e51b81526004016107199061281a565b6000610b2c82610ead565b9050610b3881846113e0565b806001600160a01b03167f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436484604051610b7391815260200190565b60405180910390a2505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bc85760405162461bcd60e51b8152600401610719906127f7565b6040516331a9108f60e11b8152600481018390526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610c30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c54919061283f565b9050610c69610c6284610ead565b8383611436565b505050565b610c788282611730565b5050565b6001600160a01b0381166000908152600b60205260408120546106af565b6001546001600160a01b03163314610ce35760405162461bcd60e51b815260206004820152600c60248201526b2737ba1037b832b930ba37b960a11b6044820152606401610719565b610cec81611ac1565b50565b60006106af82611bd0565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610d425760405162461bcd60e51b8152600401610719906127f7565b60008211610d625760405162461bcd60e51b81526004016107199061281a565b6000610d6d82610ead565b9050610d798184611c7b565b806001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c84604051610b7391815260200190565b60405163430c208160e01b8152336004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063430c208190604401602060405180830381865afa158015610e1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e43919061285c565b610e815760405162461bcd60e51b815260206004820152600f60248201526e2737ba103a37b5b2b71037bbb732b960891b6044820152606401610719565b610c78610e8d83610ead565b8233611436565b600080610ea18484611cc2565b915091505b9250929050565b600081806001600160a01b038116146106af5760405162461bcd60e51b815260206004820152600d60248201526c15dc9bdb99c818dbdb9d995c9d609a1b6044820152606401610719565b6001600160a01b0382166000908152600f6020526040812054808203610f225760009150506106af565b6001600160a01b0384166000908152600e60205260409020610f45908285611d4c565b949350505050565b6001600160a01b0381166000908152600f60205260408120548103610f74575060006106af565b6001600160a01b03808416600081815260086020908152604080832094871683529381528382205492825260128152838220828052905291822054610fb99190611e92565b90506000610fc78483610ef8565b6001600160a01b0385166000908152600f602052604081205491925090610ff090600190612789565b90506000811561110257825b611007600184612789565b8111611100576001600160a01b0387166000818152600e60208181526040808420868552808352818520825180840190935280548352600190810154838501529585529290915292829061105c90869061287e565b8152602001908152602001600020604051806040016040529081600082015481526020016001820154815250509050600061109b8b8460000151611cc2565b50905060006110ae8c8460000151611cc2565b509050670de0b6b3a76400006110c48383612789565b85602001516110d391906127b6565b6110dd91906127d5565b6110e7908761287e565b95505050505080806110f890612770565b915050610ffc565b505b6001600160a01b0386166000908152600e6020908152604080832085845282528083208151808301909252805480835260019091015492820192909252919061114c908a90611cc2565b506001600160a01b03808b166000908152600960209081526040808320938d1683529290522054909150670de0b6b3a76400009061118b908390611e92565b6111948b611bd0565b61119e9190612789565b83602001516111ad91906127b6565b6111b791906127d5565b6111c1908461287e565b9998505050505050505050565b6001600160a01b038316600090815260066020908152604080832054600790925282205460115483929190830361120857925090506113b6565b6001600160a01b03871660009081526004602052604081205490036112335792504291506113b69050565b600061123e836113be565b9050600061125a60016011546112549190612789565b89611ea9565b9050801561133357815b61126f600183612789565b811161133157600081815260106020908152604091829020825180840190935280548352600101549082018190521561131e5760006010816112b285600161287e565b81526020019081526020016000206040518060400160405290816000820154815260200160018201548152505090506000806112fd8e8460000151866000015187602001518d611eb8565b909250905061130c828961287e565b97506113198e8983611f3c565b975050505b508061132981612770565b915050611264565b505b86156113ad5760008181526010602090815260409182902082518084019093528054835260010154908201819052156113ab57600061138c8b6113758d612045565b8451611381908a611e92565b85602001518a611eb8565b509050611399818661287e565b94506113a68b8642611f3c565b429550505b505b50909350909150505b935093915050565b6011546000908082036113d45750600092915050565b6106c160108285611d4c565b6113e8612069565b80600a60008282546113fa9190612789565b90915550506001600160a01b0382166000908152600b602052604081208054839290611427908490612789565b90915550610c789050826120ed565b6000546001146114795760405162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b6044820152606401610719565b600260009081555b825181101561171c576114b183828151811061149f5761149f612744565b602002602001015160001960016111ce565b600760008685815181106114c7576114c7612744565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006006600088878151811061150757611507612744565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000849190505583919050555050600061156284838151811061155457611554612744565b602002602001015186610f4d565b9050426008600086858151811061157b5761157b612744565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000876001600160a01b03166001600160a01b0316815260200190815260200160002081905550600760008584815181106115e0576115e0612744565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020546009600086858151811061161f5761161f612744565b6020908102919091018101516001600160a01b0390811683528282019390935260409182016000908120938a168152929052902055801561169157611691838286858151811061167157611671612744565b60200260200101516001600160a01b03166121709092919063ffffffff16565b8382815181106116a3576116a3612744565b60200260200101516001600160a01b0316336001600160a01b03167fe4394b3c25e336e9d6b7fcefab7e3234f1c6b373f13655dc3920664b080b098d83866040516117019291909182526001600160a01b0316602082015260400190565b60405180910390a3508061171481612770565b915050611481565b50611726836120ed565b5050600160005550565b6000546001146117735760405162461bcd60e51b815260206004820152600e60248201526d1499595b9d1c985b9d0818d85b1b60921b6044820152606401610719565b60026000556001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116908316036117f35760405162461bcd60e51b815260206004820152601760248201527f57726f6e6720746f6b656e20666f7220726577617264730000000000000000006044820152606401610719565b600081116118135760405162461bcd60e51b81526004016107199061281a565b6001600160a01b0382166000908152600d602052604090205460ff1661186f5760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b6044820152606401610719565b6001600160a01b038216600090815260046020526040812054900361189a5761189a82600042611f3c565b6118a88260001960016111ce565b6001600160a01b0384166000908152600760209081526040808320600683528184209490945593909255600590915220544210611932576118f46001600160a01b0383163330846121d3565b62093a8061190a670de0b6b3a7640000836127b6565b61191491906127d5565b6001600160a01b038316600090815260046020526040902055611a52565b6001600160a01b038216600090815260056020526040812054611956904290612789565b6001600160a01b0384166000908152600460205260408120549192509061197d90836127b6565b9050611991670de0b6b3a7640000826127d5565b83116119f65760405162461bcd60e51b815260206004820152602e60248201527f416d6f756e742073686f756c6420626520686967686572207468616e2072656d60448201526d61696e696e67207265776172647360901b6064820152608401610719565b611a0b6001600160a01b0385163330866121d3565b62093a8081611a22670de0b6b3a7640000866127b6565b611a2c919061287e565b611a3691906127d5565b6001600160a01b03851660009081526004602052604090205550505b611a5f62093a804261287e565b6001600160a01b0383166000818152600560205260409081902092909255905133907ff70d5c697de7ea828df48e5c4573cb2194c659f1901f70110c52b066dcf5082690611ab09085815260200190565b60405180910390a350506001600055565b600c54600a11611b0c5760405162461bcd60e51b8152602060048201526016602482015275546f6f206d616e792072657761726420746f6b656e7360501b6044820152606401610719565b6001600160a01b0381166000908152600d602052604090205460ff1615611b6a5760405162461bcd60e51b8152602060048201526012602482015271105b1c9958591e481c9959da5cdd195c995960721b6044820152606401610719565b6001600160a01b03166000818152600d60205260408120805460ff19166001908117909155600c805491820181559091527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c70180546001600160a01b0319169091179055565b6000600254600003611bf857506001600160a01b031660009081526007602052604090205490565b6002546001600160a01b03831660009081526004602090815260408083205460068352818420546005909352922054611c319190611ea9565b611c3a85612045565b611c449190612789565b611c4e91906127b6565b611c5891906127d5565b6001600160a01b0383166000908152600760205260409020546106af919061287e565b611c83612069565b80600a6000828254611c95919061287e565b90915550506001600160a01b0382166000908152600b60205260408120805483929061142790849061287e565b6001600160a01b0382166000908152601360205260408120548190808203611cf1576000809250925050610ea6565b6001600160a01b038516600090815260126020526040812090611d15828488611d4c565b6000908152602092835260409081902081518083019092528054808352600190910154919093018190529791965090945050505050565b600082600003611d925760405162461bcd60e51b8152602060048201526011602482015270456d70747920636865636b706f696e747360781b6044820152606401610719565b81846000611da1600187612789565b81526020019081526020016000206000015411611dca57611dc3600184612789565b90506106c1565b600080805260208590526040902054821015611de8575060006106c1565b600080611df6600186612789565b90505b81811115611e895760006002611e0f8484612789565b611e1991906127d5565b611e239083612789565b60008181526020898152604091829020825180840190935280548084526001909101549183019190915291925090869003611e63575092506106c1915050565b8051861115611e7457819350611e82565b611e7f600183612789565b92505b5050611df9565b50949350505050565b600081831015611ea257816106c1565b5090919050565b6000818310611ea257816106c1565b6000806000611ec78785611e92565b6001600160a01b038916600090815260056020908152604080832054600490925290912054919250908690611f05611eff8a89611e92565b84611ea9565b611f0f8585611ea9565b611f199190612789565b611f2391906127b6565b611f2d91906127d5565b99919850909650505050505050565b6001600160a01b0383166000908152601360205260409020548015801590611f9857506001600160a01b03841660009081526012602052604081208391611f84600185612789565b815260200190815260200160002060000154145b15611fdb576001600160a01b03841660009081526012602052604081208491611fc2600185612789565b815260208101919091526040016000206001015561203f565b60408051808201825283815260208082018681526001600160a01b03881660009081526012835284812086825290925292902090518155905160019182015561202590829061287e565b6001600160a01b0385166000908152601360205260409020555b50505050565b6001600160a01b0381166000908152600560205260408120546106af904290611ea9565b600c5460005b81811015610c78576000600c828154811061208c5761208c612744565b6000918252602090912001546001600160a01b031690506120b18160001960016111ce565b6001600160a01b0390921660009081526007602090815260408083206006909252909120929092559055806120e581612770565b91505061206f565b6001600160a01b0381166000908152600360205260408120546002805491928392612119908490612789565b9091555050506001600160a01b0381166000908152600b602090815260408083205460039092528220819055600280549192839261215890849061287e565b909155506121689050828261220b565b610c786122fc565b6040516001600160a01b038316602482015260448101829052610c6990849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526123a0565b6040516001600160a01b038085166024830152831660448201526064810182905261203f9085906323b872dd60e01b9060840161219c565b6001600160a01b0382166000908152600f60205260409020544290801580159061226957506001600160a01b0384166000908152600e602052604081208391612255600185612789565b815260200190815260200160002060000154145b15612293576001600160a01b0384166000908152600e602052604081208491611fc2600185612789565b60408051808201825283815260208082018681526001600160a01b0388166000908152600e83528481208682529092529290209051815590516001918201556122dd90829061287e565b6001600160a01b0385166000908152600f602052604090205550505050565b60115442811580159061232e5750806010600061231a600186612789565b815260200190815260200160002060000154145b1561235d5760025460106000612345600186612789565b81526020810191909152604001600020600101555050565b6040805180820182528281526002546020808301918252600086815260109091529290922090518155905160019182015561239990839061287e565b6011555050565b60006123f5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166124729092919063ffffffff16565b805190915015610c695780806020019051810190612413919061285c565b610c695760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610719565b60606001600160a01b0384163b6124cb5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610719565b600080856001600160a01b0316856040516124e691906128c2565b6000604051808303816000865af19150503d8060008114612523576040519150601f19603f3d011682016040523d82523d6000602084013e612528565b606091505b5091509150612538828286612542565b9695505050505050565b606083156125515750816106c1565b8251156125615782518084602001fd5b8160405162461bcd60e51b815260040161071991906128de565b6001600160a01b0381168114610cec57600080fd5b803561259b8161257b565b919050565b600080604083850312156125b357600080fd5b82356125be8161257b565b946020939093013593505050565b6000602082840312156125de57600080fd5b5035919050565b600080604083850312156125f857600080fd5b82356126038161257b565b915060208301356126138161257b565b809150509250929050565b60006020828403121561263057600080fd5b81356106c18161257b565b6000806040838503121561264e57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561268657600080fd5b8235915060208084013567ffffffffffffffff808211156126a657600080fd5b818601915086601f8301126126ba57600080fd5b8135818111156126cc576126cc61265d565b8060051b604051601f19603f830116810181811085821117156126f1576126f161265d565b60405291825284820192508381018501918983111561270f57600080fd5b938501935b828510156127345761272585612590565b84529385019392850192612714565b8096505050505050509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016127825761278261275a565b5060010190565b60008282101561279b5761279b61275a565b500390565b634e487b7160e01b600052603160045260246000fd5b60008160001904831182151516156127d0576127d061275a565b500290565b6000826127f257634e487b7160e01b600052601260045260246000fd5b500490565b6020808252600990820152682737ba103b37ba32b960b91b604082015260600190565b6020808252600b908201526a16995c9bc8185b5bdd5b9d60aa1b604082015260600190565b60006020828403121561285157600080fd5b81516106c18161257b565b60006020828403121561286e57600080fd5b815180151581146106c157600080fd5b600082198211156128915761289161275a565b500190565b60005b838110156128b1578181015183820152602001612899565b8381111561203f5750506000910152565b600082516128d4818460208701612896565b9190910192915050565b60208152600082518060208401526128fd816040850160208701612896565b601f01601f1916919091016040019291505056fea26469706673582212203a96e6088b0b370ddb7df141bb1eacf5da3a10634caf16402c5764bbdca6564964736f6c634300080d0033000000000000000000000000649bdf58b09a0cd4ac848b42c4b5e1390a72a49a000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270000000000000000000000000c2132d05d31c914a87c6611c10748aeb04b58e8f00000000000000000000000039ab6574c289c3ae4d88500eec792ab5b947a5eb
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.