Contract Overview
Contract Name:
WrappedExternalBribeFactory
Compiler Version
v0.8.13+commit.abaa5c0e
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import {WrappedExternalBribe} from 'contracts/WrappedExternalBribe.sol'; contract WrappedExternalBribeFactory { address public immutable voter; mapping(address => address) public oldBribeToNew; address public last_bribe; constructor(address _voter) { voter = _voter; } function createBribe(address existing_bribe) external returns (address) { require( oldBribeToNew[existing_bribe] == address(0), "Wrapped bribe already created" ); last_bribe = address(new WrappedExternalBribe(voter, existing_bribe)); oldBribeToNew[existing_bribe] = last_bribe; return last_bribe; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IBribe { function _deposit(uint amount, uint tokenId) external; function _withdraw(uint amount, uint tokenId) external; function getRewardForOwner(uint tokenId, address[] memory tokens) external; function notifyRewardAmount(address token, uint amount) external; function left(address token) external view returns (uint); }
// 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 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; } } function cbrt(uint256 n) internal pure returns (uint256) { unchecked { uint256 x = 0; for (uint256 y = 1 << 255; y > 0; y >>= 3) { x <<= 1; uint256 z = 3 * x * (x + 1) + 1; if (n / y >= z) { n -= y * z; x += 1; } } return x; }} }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IVotingEscrow { struct Point { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block } struct LockedBalance { int128 amount; uint end; } function create_lock_for(uint _value, uint _lock_duration, address _to) external returns (uint); function locked(uint id) external view returns(LockedBalance memory); function tokenOfOwnerByIndex(address _owner, uint _tokenIndex) external view returns (uint); function token() external view returns (address); function team() external returns (address); function epoch() external view returns (uint); function point_history(uint loc) external view returns (Point memory); function user_point_history(uint tokenId, uint loc) external view returns (Point memory); function user_point_epoch(uint tokenId) external view returns (uint); function ownerOf(uint) external view returns (address); function isApprovedOrOwner(address, uint) external view returns (bool); function transferFrom(address, address, uint) external; function voted(uint) external view returns (bool); function attachments(uint) external view returns (uint); function voting(uint tokenId) external; function abstain(uint tokenId) external; function attach(uint tokenId) external; function detach(uint tokenId) external; function checkpoint() external; function deposit_for(uint tokenId, uint value) external; function balanceOfNFT(uint _id) external view returns (uint); function balanceOf(address _owner) external view returns (uint); function totalSupply() external view returns (uint); function supply() external view returns (uint); function decimals() external view returns(uint8); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import './libraries/Math.sol'; import './ExternalBribe.sol'; import './interfaces/IERC20.sol'; import './interfaces/IGauge.sol'; import './interfaces/IVoter.sol'; import './interfaces/IVotingEscrow.sol'; // Bribes pay out rewards for a given pool based on the votes that were received from the user (goes hand in hand with Voter.vote()) contract WrappedExternalBribe { address public immutable voter; address public immutable _ve; ExternalBribe public underlying_bribe; uint internal constant DURATION = 7 days; // rewards are released over the voting period uint internal constant MAX_REWARD_TOKENS = 16; uint internal constant PRECISION = 10 ** 18; mapping(address => mapping(uint => uint)) public tokenRewardsPerEpoch; mapping(address => uint) public periodFinish; mapping(address => mapping(uint => uint)) public lastEarn; address[] public rewards; mapping(address => bool) public isReward; /// @notice A checkpoint for marking balance struct RewardCheckpoint { uint timestamp; uint balance; } event NotifyReward(address indexed from, address indexed reward, uint epoch, uint amount); event ClaimRewards(address indexed from, address indexed reward, uint amount); constructor(address _voter, address _old_bribe) { voter = _voter; _ve = IVoter(_voter)._ve(); underlying_bribe = ExternalBribe(_old_bribe); for (uint i; i < underlying_bribe.rewardsListLength(); i++) { address underlying_reward = underlying_bribe.rewards(i); if (underlying_reward != address(0)) { isReward[underlying_reward] = true; rewards.push(underlying_reward); } } } // simple re-entrancy check uint internal _unlocked = 1; modifier lock() { require(_unlocked == 1); _unlocked = 2; _; _unlocked = 1; } function _bribeStart(uint timestamp) internal pure returns (uint) { return timestamp - (timestamp % (7 days)); } function getEpochStart(uint timestamp) public pure returns (uint) { uint bribeStart = _bribeStart(timestamp); uint bribeEnd = bribeStart + DURATION; return timestamp < bribeEnd ? bribeStart : bribeStart + 7 days; } function rewardsListLength() external view returns (uint) { return rewards.length; } // returns the last time the reward was modified or periodFinish if the reward has ended function lastTimeRewardApplicable(address token) public view returns (uint) { return Math.min(block.timestamp, periodFinish[token]); } // allows a user to claim rewards for a given token function getReward(uint tokenId, address[] memory tokens) external lock { require(IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, tokenId)); for (uint i = 0; i < tokens.length; i++) { uint _reward = earned(tokens[i], tokenId); lastEarn[tokens[i]][tokenId] = block.timestamp; if (_reward > 0) _safeTransfer(tokens[i], msg.sender, _reward); emit ClaimRewards(msg.sender, tokens[i], _reward); } } // used by Voter to allow batched reward claims function getRewardForOwner(uint tokenId, address[] memory tokens) external lock { require(msg.sender == voter); address _owner = IVotingEscrow(_ve).ownerOf(tokenId); for (uint i = 0; i < tokens.length; i++) { uint _reward = earned(tokens[i], tokenId); lastEarn[tokens[i]][tokenId] = block.timestamp; if (_reward > 0) _safeTransfer(tokens[i], _owner, _reward); emit ClaimRewards(_owner, tokens[i], _reward); } } function earned(address token, uint tokenId) public view returns (uint) { uint _startTimestamp = lastEarn[token][tokenId]; if (underlying_bribe.numCheckpoints(tokenId) == 0) { return 0; } uint _startIndex = underlying_bribe.getPriorBalanceIndex(tokenId, _startTimestamp); uint _endIndex = underlying_bribe.numCheckpoints(tokenId)-1; uint reward = 0; // you only earn once per epoch (after it's over) RewardCheckpoint memory prevRewards; prevRewards.timestamp = _bribeStart(_startTimestamp); uint _prevTs = 0; uint _prevBal = 0; uint _prevSupply = 1; if (_endIndex > 0) { for (uint i = _startIndex; i <= _endIndex - 1; i++) { (_prevTs, _prevBal) = underlying_bribe.checkpoints(tokenId,i); uint _nextEpochStart = _bribeStart(_prevTs); // check that you've earned it // this won't happen until a week has passed if (_nextEpochStart > prevRewards.timestamp) { reward += prevRewards.balance; } prevRewards.timestamp = _nextEpochStart; (, _prevSupply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(_nextEpochStart + DURATION)); prevRewards.balance = _prevBal * tokenRewardsPerEpoch[token][_nextEpochStart] / _prevSupply; } } (_prevTs, _prevBal) = underlying_bribe.checkpoints(tokenId,_endIndex); uint _lastEpochStart = _bribeStart(_prevTs); uint _lastEpochEnd = _lastEpochStart + DURATION; if (block.timestamp > _lastEpochEnd && _startTimestamp < _lastEpochEnd) { (, _prevSupply) = underlying_bribe.supplyCheckpoints(underlying_bribe.getPriorSupplyIndex(_lastEpochEnd)); reward += _prevBal * tokenRewardsPerEpoch[token][_lastEpochStart] / _prevSupply; } return reward; } function left(address token) external view returns (uint) { uint adjustedTstamp = getEpochStart(block.timestamp); return tokenRewardsPerEpoch[token][adjustedTstamp]; } function notifyRewardAmount(address token, uint amount) external lock { require(amount > 0); if (!isReward[token]) { require(IVoter(voter).isWhitelisted(token), "bribe tokens must be whitelisted"); require(rewards.length < MAX_REWARD_TOKENS, "too many rewards tokens"); } // bribes kick in at the start of next bribe period uint adjustedTstamp = getEpochStart(block.timestamp); uint epochRewards = tokenRewardsPerEpoch[token][adjustedTstamp]; _safeTransferFrom(token, msg.sender, address(this), amount); tokenRewardsPerEpoch[token][adjustedTstamp] = epochRewards + amount; periodFinish[token] = adjustedTstamp + DURATION; if (!isReward[token]) { isReward[token] = true; rewards.push(token); } emit NotifyReward(msg.sender, token, adjustedTstamp, amount); } function swapOutRewardToken(uint i, address oldToken, address newToken) external { require(msg.sender == IVotingEscrow(_ve).team(), 'only team'); require(rewards[i] == oldToken); isReward[oldToken] = false; isReward[newToken] = true; rewards[i] = newToken; } function _safeTransfer(address token, address to, uint256 value) internal { require(token.code.length > 0); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool)))); } function _safeTransferFrom(address token, address from, address to, uint256 value) internal { require(token.code.length > 0); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool)))); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import './libraries/Math.sol'; import './interfaces/IBribe.sol'; import './interfaces/IERC20.sol'; import './interfaces/IGauge.sol'; import './interfaces/IVoter.sol'; import './interfaces/IVotingEscrow.sol'; // Bribes pay out rewards for a given pool based on the votes that were received from the user (goes hand in hand with Voter.vote()) contract ExternalBribe is IBribe { address public immutable voter; // only voter can modify balances (since it only happens on vote()) address public immutable _ve; uint internal constant DURATION = 7 days; // rewards are released over the voting period uint internal constant MAX_REWARD_TOKENS = 16; uint internal constant PRECISION = 10 ** 18; uint public totalSupply; mapping(uint => uint) public balanceOf; mapping(address => mapping(uint => uint)) public tokenRewardsPerEpoch; mapping(address => uint) public periodFinish; mapping(address => mapping(uint => uint)) public lastEarn; address[] public rewards; mapping(address => bool) public isReward; /// @notice A checkpoint for marking balance struct Checkpoint { uint timestamp; uint balanceOf; } /// @notice A checkpoint for marking supply struct SupplyCheckpoint { uint timestamp; uint supply; } /// @notice A record of balance checkpoints for each account, by index mapping (uint => mapping (uint => Checkpoint)) public checkpoints; /// @notice The number of checkpoints for each account mapping (uint => uint) public numCheckpoints; /// @notice A record of balance checkpoints for each token, by index mapping (uint => SupplyCheckpoint) public supplyCheckpoints; /// @notice The number of checkpoints uint public supplyNumCheckpoints; event Deposit(address indexed from, uint tokenId, uint amount); event Withdraw(address indexed from, uint tokenId, uint amount); event NotifyReward(address indexed from, address indexed reward, uint epoch, uint amount); event ClaimRewards(address indexed from, address indexed reward, uint amount); constructor(address _voter, address[] memory _allowedRewardTokens) { voter = _voter; _ve = IVoter(_voter)._ve(); for (uint i; i < _allowedRewardTokens.length; i++) { if (_allowedRewardTokens[i] != address(0)) { isReward[_allowedRewardTokens[i]] = true; rewards.push(_allowedRewardTokens[i]); } } } // simple re-entrancy check uint internal _unlocked = 1; modifier lock() { require(_unlocked == 1); _unlocked = 2; _; _unlocked = 1; } function _bribeStart(uint timestamp) internal pure returns (uint) { return timestamp - (timestamp % (7 days)); } function getEpochStart(uint timestamp) public pure returns (uint) { uint bribeStart = _bribeStart(timestamp); uint bribeEnd = bribeStart + DURATION; return timestamp < bribeEnd ? bribeStart : bribeStart + 7 days; } /** * @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 tokenId The token of the NFT to check * @param timestamp The timestamp to get the balance at * @return The balance the account had as of the given block */ function getPriorBalanceIndex(uint tokenId, uint timestamp) public view returns (uint) { uint nCheckpoints = numCheckpoints[tokenId]; if (nCheckpoints == 0) { return 0; } // First check most recent balance if (checkpoints[tokenId][nCheckpoints - 1].timestamp <= timestamp) { return (nCheckpoints - 1); } // Next check implicit zero balance if (checkpoints[tokenId][0].timestamp > timestamp) { return 0; } uint lower = 0; uint upper = nCheckpoints - 1; while (upper > lower) { uint center = upper - (upper - lower) / 2; // ceil, avoiding overflow Checkpoint memory cp = checkpoints[tokenId][center]; if (cp.timestamp == timestamp) { return center; } else if (cp.timestamp < timestamp) { lower = center; } else { upper = center - 1; } } return lower; } function getPriorSupplyIndex(uint timestamp) public view returns (uint) { uint nCheckpoints = supplyNumCheckpoints; if (nCheckpoints == 0) { return 0; } // First check most recent balance if (supplyCheckpoints[nCheckpoints - 1].timestamp <= timestamp) { return (nCheckpoints - 1); } // Next check implicit zero balance if (supplyCheckpoints[0].timestamp > timestamp) { return 0; } uint lower = 0; uint upper = nCheckpoints - 1; while (upper > lower) { uint center = upper - (upper - lower) / 2; // ceil, avoiding overflow SupplyCheckpoint memory cp = supplyCheckpoints[center]; if (cp.timestamp == timestamp) { return center; } else if (cp.timestamp < timestamp) { lower = center; } else { upper = center - 1; } } return lower; } function _writeCheckpoint(uint tokenId, uint balance) internal { uint _timestamp = block.timestamp; uint _nCheckPoints = numCheckpoints[tokenId]; if (_nCheckPoints > 0 && checkpoints[tokenId][_nCheckPoints - 1].timestamp == _timestamp) { checkpoints[tokenId][_nCheckPoints - 1].balanceOf = balance; } else { checkpoints[tokenId][_nCheckPoints] = Checkpoint(_timestamp, balance); numCheckpoints[tokenId] = _nCheckPoints + 1; } } function _writeSupplyCheckpoint() internal { uint _nCheckPoints = supplyNumCheckpoints; uint _timestamp = block.timestamp; if (_nCheckPoints > 0 && supplyCheckpoints[_nCheckPoints - 1].timestamp == _timestamp) { supplyCheckpoints[_nCheckPoints - 1].supply = totalSupply; } else { supplyCheckpoints[_nCheckPoints] = SupplyCheckpoint(_timestamp, totalSupply); supplyNumCheckpoints = _nCheckPoints + 1; } } function rewardsListLength() external view returns (uint) { return rewards.length; } // returns the last time the reward was modified or periodFinish if the reward has ended function lastTimeRewardApplicable(address token) public view returns (uint) { return Math.min(block.timestamp, periodFinish[token]); } // allows a user to claim rewards for a given token function getReward(uint tokenId, address[] memory tokens) external lock { require(IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, tokenId)); for (uint i = 0; i < tokens.length; i++) { uint _reward = earned(tokens[i], tokenId); lastEarn[tokens[i]][tokenId] = block.timestamp; if (_reward > 0) _safeTransfer(tokens[i], msg.sender, _reward); emit ClaimRewards(msg.sender, tokens[i], _reward); } } // used by Voter to allow batched reward claims function getRewardForOwner(uint tokenId, address[] memory tokens) external lock { require(msg.sender == voter); address _owner = IVotingEscrow(_ve).ownerOf(tokenId); for (uint i = 0; i < tokens.length; i++) { uint _reward = earned(tokens[i], tokenId); lastEarn[tokens[i]][tokenId] = block.timestamp; if (_reward > 0) _safeTransfer(tokens[i], _owner, _reward); emit ClaimRewards(_owner, tokens[i], _reward); } } function earned(address token, uint tokenId) public view returns (uint) { uint _startTimestamp = lastEarn[token][tokenId]; if (numCheckpoints[tokenId] == 0) { return 0; } uint _startIndex = getPriorBalanceIndex(tokenId, _startTimestamp); uint _endIndex = numCheckpoints[tokenId]-1; uint reward = 0; // you only earn once per epoch (after it's over) Checkpoint memory prevRewards; // reuse struct to avoid stack too deep prevRewards.timestamp = _bribeStart(_startTimestamp); uint _prevSupply = 1; if (_endIndex > 0) { for (uint i = _startIndex; i <= _endIndex - 1; i++) { Checkpoint memory cp0 = checkpoints[tokenId][i]; uint _nextEpochStart = _bribeStart(cp0.timestamp); // check that you've earned it // this won't happen until a week has passed if (_nextEpochStart > prevRewards.timestamp) { reward += prevRewards.balanceOf; } prevRewards.timestamp = _nextEpochStart; _prevSupply = supplyCheckpoints[getPriorSupplyIndex(_nextEpochStart + DURATION)].supply; prevRewards.balanceOf = cp0.balanceOf * tokenRewardsPerEpoch[token][_nextEpochStart] / _prevSupply; } } Checkpoint memory cp = checkpoints[tokenId][_endIndex]; uint _lastEpochStart = _bribeStart(cp.timestamp); uint _lastEpochEnd = _lastEpochStart + DURATION; if (block.timestamp > _lastEpochEnd) { reward += cp.balanceOf * tokenRewardsPerEpoch[token][_lastEpochStart] / supplyCheckpoints[getPriorSupplyIndex(_lastEpochEnd)].supply; } return reward; } // 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 { require(msg.sender == voter); totalSupply += amount; balanceOf[tokenId] += amount; _writeCheckpoint(tokenId, balanceOf[tokenId]); _writeSupplyCheckpoint(); emit Deposit(msg.sender, tokenId, amount); } function _withdraw(uint amount, uint tokenId) external { require(msg.sender == voter); totalSupply -= amount; balanceOf[tokenId] -= amount; _writeCheckpoint(tokenId, balanceOf[tokenId]); _writeSupplyCheckpoint(); emit Withdraw(msg.sender, tokenId, amount); } function left(address token) external view returns (uint) { uint adjustedTstamp = getEpochStart(block.timestamp); return tokenRewardsPerEpoch[token][adjustedTstamp]; } function notifyRewardAmount(address token, uint amount) external lock { require(amount > 0); if (!isReward[token]) { require(IVoter(voter).isWhitelisted(token), "bribe tokens must be whitelisted"); require(rewards.length < MAX_REWARD_TOKENS, "too many rewards tokens"); } // bribes kick in at the start of next bribe period uint adjustedTstamp = getEpochStart(block.timestamp); uint epochRewards = tokenRewardsPerEpoch[token][adjustedTstamp]; _safeTransferFrom(token, msg.sender, address(this), amount); tokenRewardsPerEpoch[token][adjustedTstamp] = epochRewards + amount; periodFinish[token] = adjustedTstamp + DURATION; if (!isReward[token]) { isReward[token] = true; rewards.push(token); } emit NotifyReward(msg.sender, token, adjustedTstamp, amount); } function swapOutRewardToken(uint i, address oldToken, address newToken) external { require(msg.sender == IVotingEscrow(_ve).team(), 'only team'); require(rewards[i] == oldToken); isReward[oldToken] = false; isReward[newToken] = true; rewards[i] = newToken; } function _safeTransfer(address token, address to, uint256 value) internal { require(token.code.length > 0); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool)))); } function _safeTransferFrom(address token, address from, address to, uint256 value) internal { require(token.code.length > 0); (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool)))); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IERC20 { function totalSupply() external view returns (uint256); function transfer(address recipient, uint amount) external returns (bool); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function balanceOf(address) external view returns (uint); function transferFrom(address sender, address recipient, uint amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IGauge { function notifyRewardAmount(address token, uint amount) external; function getReward(address account, address[] memory tokens) external; function claimFees() external returns (uint claimed0, uint claimed1); function left(address token) external view returns (uint); function rewardRate(address _pair) external view returns (uint); function balanceOf(address _account) external view returns (uint); function isForPair() external view returns (bool); function totalSupply() external view returns (uint); function earned(address token, address account) external view returns (uint); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IVoter { function _ve() external view returns (address); function governor() external view returns (address); function gauges(address _pair) external view returns (address); function factory() external view returns (address); function minter() external view returns(address); function emergencyCouncil() 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 isWhitelisted(address token) external view returns (bool); function notifyRewardAmount(uint amount) external; function distribute(address _gauge) external; function distributeAll() external; function distributeFees(address[] memory _gauges) external; function internal_bribes(address _gauge) external view returns (address); function external_bribes(address _gauge) external view returns (address); function usedWeights(uint id) external view returns(uint); function lastVoted(uint id) external view returns(uint); function poolVote(uint id, uint _index) external view returns(address _pair); function votes(uint id, address _pool) external view returns(uint votes); function poolVoteLength(uint tokenId) external view returns(uint); }
[{"inputs":[{"internalType":"address","name":"_voter","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"existing_bribe","type":"address"}],"name":"createBribe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"last_bribe","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"oldBribeToNew","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
608060405234801561001057600080fd5b506004361061004c5760003560e01c80632fcd8f271461005157806346c96aac146100965780636bd1a72c146100bd578063b1d0fc82146100d0575b600080fd5b61007a61005f366004610205565b6000602081905290815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b61007a7f000000000000000000000000000000000000000000000000000000000000000081565b61007a6100cb366004610205565b6100e3565b60015461007a906001600160a01b031681565b6001600160a01b03818116600090815260208190526040812054909116156101515760405162461bcd60e51b815260206004820152601d60248201527f5772617070656420627269626520616c72656164792063726561746564000000604482015260640160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000008260405161017f906101f8565b6001600160a01b03928316815291166020820152604001604051809103906000f0801580156101b2573d6000803e3d6000fd5b50600180546001600160a01b039283166001600160a01b031991821681178355948316600090815260208190526040902080549091169094179093559154909116919050565b611a618061023683390190565b60006020828403121561021757600080fd5b81356001600160a01b038116811461022e57600080fd5b939250505056fe60c060405260016006553480156200001657600080fd5b5060405162001a6138038062001a61833981016040819052620000399162000275565b6001600160a01b038216608081905260408051638dd598fb60e01b81529051638dd598fb916004808201926020929091908290030181865afa15801562000084573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000aa9190620002ad565b6001600160a01b0390811660a052600080546001600160a01b0319169183169190911781555b60008054906101000a90046001600160a01b03166001600160a01b031663e68863966040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000122573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001489190620002d2565b8110156200024f5760008054604051637980d7a160e11b8152600481018490526001600160a01b039091169063f301af4290602401602060405180830381865afa1580156200019b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001c19190620002ad565b90506001600160a01b0381161562000239576001600160a01b0381166000818152600560205260408120805460ff191660019081179091556004805491820181559091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b03191690911790555b50806200024681620002ec565b915050620000d0565b50505062000314565b80516001600160a01b03811681146200027057600080fd5b919050565b600080604083850312156200028957600080fd5b620002948362000258565b9150620002a46020840162000258565b90509250929050565b600060208284031215620002c057600080fd5b620002cb8262000258565b9392505050565b600060208284031215620002e557600080fd5b5051919050565b6000600182016200030d57634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a0516117046200035d600039600081816101e6015281816108f301528181610b1d0152610fd701526000818161014e01528181610ada0152610d1801526117046000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c80639418f939116100a2578063da09d19d11610071578063da09d19d14610281578063e6886396146102a1578063f25e55a5146102a9578063f301af42146102d4578063f5f8d365146102e757600080fd5b80639418f9391461023357806399bcc05214610248578063a7852afa1461025b578063b66503cf1461026e57600080fd5b8063638634ee116100de578063638634ee146101bb5780636c4f5398146101ce5780638dd598fb146101e157806392777b291461020857600080fd5b80630175e23b146101105780633e491d471461013657806346c96aac146101495780634d5ce03814610188575b600080fd5b61012361011e366004611393565b6102fa565b6040519081526020015b60405180910390f35b6101236101443660046113d4565b61033c565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161012d565b6101ab610196366004611400565b60056020526000908152604090205460ff1681565b604051901515815260200161012d565b6101236101c9366004611400565b6108cd565b600054610170906001600160a01b031681565b6101707f000000000000000000000000000000000000000000000000000000000000000081565b6101236102163660046113d4565b600160209081526000928352604080842090915290825290205481565b61024661024136600461141d565b6108f1565b005b610123610256366004611400565b610a82565b610246610269366004611475565b610abb565b61024661027c3660046113d4565b610cbb565b61012361028f366004611400565b60026020526000908152604090205481565b600454610123565b6101236102b73660046113d4565b600360209081526000928352604080842090915290825290205481565b6101706102e2366004611393565b610f7d565b6102466102f5366004611475565b610fa7565b6000806103068361117b565b9050600061031762093a808361155c565b90508084106103325761032d8262093a8061155c565b610334565b815b949350505050565b6001600160a01b0382811660009081526003602090815260408083208584529091528082205482549151635058979360e01b81526004810186905292939092911690635058979390602401602060405180830381865afa1580156103a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c89190611574565b6000036103d95760009150506108c7565b600080546040516328a3532760e21b815260048101869052602481018490526001600160a01b039091169063a28d4c9c90604401602060405180830381865afa15801561042a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061044e9190611574565b60008054604051635058979360e01b81526004810188905292935090916001916001600160a01b031690635058979390602401602060405180830381865afa15801561049e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c29190611574565b6104cc919061158d565b905060006104ed604051806040016040528060008152602001600081525090565b6104f68561117b565b8152600080600185156106f357865b61051060018861158d565b81116106f157600054604051631277308160e21b8152600481018d9052602481018390526001600160a01b03909116906349dcc204906044016040805180830381865afa158015610565573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058991906115a4565b909450925060006105998561117b565b86519091508111156105b75760208601516105b4908861155c565b96505b8086526000546001600160a01b031663f7412baf816376f4be366105de62093a808661155c565b6040518263ffffffff1660e01b81526004016105fc91815260200190565b602060405180830381865afa158015610619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063d9190611574565b6040518263ffffffff1660e01b815260040161065b91815260200190565b6040805180830381865afa158015610677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061069b91906115a4565b6001600160a01b038f1660009081526001602090815260408083208684529091529020549094508491506106cf90866115c8565b6106d991906115fd565b602087015250806106e981611611565b915050610505565b505b600054604051631277308160e21b8152600481018c9052602481018890526001600160a01b03909116906349dcc204906044016040805180830381865afa158015610742573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076691906115a4565b909350915060006107768461117b565b9050600061078762093a808361155c565b905080421180156107975750808a105b156108ba57600054604051633b7a5f1b60e11b8152600481018390526001600160a01b039091169063f7412baf9082906376f4be3690602401602060405180830381865afa1580156107ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108119190611574565b6040518263ffffffff1660e01b815260040161082f91815260200190565b6040805180830381865afa15801561084b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061086f91906115a4565b6001600160a01b038f1660009081526001602090815260408083208784529091529020549094508491506108a390866115c8565b6108ad91906115fd565b6108b7908861155c565b96505b5094985050505050505050505b92915050565b6001600160a01b0381166000908152600260205260408120546108c7904290611194565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166385f2aef26040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610951573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610975919061162a565b6001600160a01b0316336001600160a01b0316146109c65760405162461bcd60e51b81526020600482015260096024820152686f6e6c79207465616d60b81b60448201526064015b60405180910390fd5b816001600160a01b0316600484815481106109e3576109e3611647565b6000918252602090912001546001600160a01b031614610a0257600080fd5b6001600160a01b03808316600090815260056020526040808220805460ff1990811690915592841682529020805490911660011790556004805482919085908110610a4f57610a4f611647565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505050565b600080610a8e426102fa565b6001600160a01b039093166000908152600160209081526040808320958352949052929092205492915050565b600654600114610aca57600080fd5b6002600655336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b0457600080fd5b6040516331a9108f60e11b8152600481018390526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690636352211e90602401602060405180830381865afa158015610b6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b90919061162a565b905060005b8251811015610cb0576000610bc3848381518110610bb557610bb5611647565b60200260200101518661033c565b90504260036000868581518110610bdc57610bdc611647565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020558015610c3757610c37848381518110610c2857610c28611647565b602002602001015184836111ac565b838281518110610c4957610c49611647565b60200260200101516001600160a01b0316836001600160a01b03167f9aa05b3d70a9e3e2f004f039648839560576334fb45c81f91b6db03ad9e2efc983604051610c9591815260200190565b60405180910390a35080610ca881611611565b915050610b95565b505060016006555050565b600654600114610cca57600080fd5b600260065580610cd957600080fd5b6001600160a01b03821660009081526005602052604090205460ff16610e2157604051633af32abf60e01b81526001600160a01b0383811660048301527f00000000000000000000000000000000000000000000000000000000000000001690633af32abf90602401602060405180830381865afa158015610d5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d83919061165d565b610dcf5760405162461bcd60e51b815260206004820181905260248201527f627269626520746f6b656e73206d7573742062652077686974656c697374656460448201526064016109bd565b600454601011610e215760405162461bcd60e51b815260206004820152601760248201527f746f6f206d616e79207265776172647320746f6b656e7300000000000000000060448201526064016109bd565b6000610e2c426102fa565b6001600160a01b0384166000908152600160209081526040808320848452909152902054909150610e5f8433308661129b565b610e69838261155c565b6001600160a01b0385166000908152600160209081526040808320868452909152902055610e9a62093a808361155c565b6001600160a01b03851660009081526002602090815260408083209390935560059052205460ff16610f2c576001600160a01b0384166000818152600560205260408120805460ff191660019081179091556004805491820181559091527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b03191690911790555b60408051838152602081018590526001600160a01b0386169133917f52977ea98a2220a03ee9ba5cb003ada08d394ea10155483c95dc2dc77a7eb24b910160405180910390a3505060016006555050565b60048181548110610f8d57600080fd5b6000918252602090912001546001600160a01b0316905081565b600654600114610fb657600080fd5b600260065560405163430c208160e01b8152336004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063430c208190604401602060405180830381865afa158015611026573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104a919061165d565b61105357600080fd5b60005b815181101561117157600061108483838151811061107657611076611647565b60200260200101518561033c565b9050426003600085858151811061109d5761109d611647565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812088825290925290205580156110f8576110f88383815181106110e9576110e9611647565b602002602001015133836111ac565b82828151811061110a5761110a611647565b60200260200101516001600160a01b0316336001600160a01b03167f9aa05b3d70a9e3e2f004f039648839560576334fb45c81f91b6db03ad9e2efc98360405161115691815260200190565b60405180910390a3508061116981611611565b915050611056565b5050600160065550565b600061118a62093a808361167f565b6108c7908361158d565b60008183106111a357816111a5565b825b9392505050565b6000836001600160a01b03163b116111c357600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161121f9190611693565b6000604051808303816000865af19150503d806000811461125c576040519150601f19603f3d011682016040523d82523d6000602084013e611261565b606091505b509150915081801561128b57508051158061128b57508080602001905181019061128b919061165d565b61129457600080fd5b5050505050565b6000846001600160a01b03163b116112b257600080fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291516000928392908816916113169190611693565b6000604051808303816000865af19150503d8060008114611353576040519150601f19603f3d011682016040523d82523d6000602084013e611358565b606091505b5091509150818015611382575080511580611382575080806020019051810190611382919061165d565b61138b57600080fd5b505050505050565b6000602082840312156113a557600080fd5b5035919050565b6001600160a01b03811681146113c157600080fd5b50565b80356113cf816113ac565b919050565b600080604083850312156113e757600080fd5b82356113f2816113ac565b946020939093013593505050565b60006020828403121561141257600080fd5b81356111a5816113ac565b60008060006060848603121561143257600080fd5b833592506020840135611444816113ac565b91506040840135611454816113ac565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561148857600080fd5b8235915060208084013567ffffffffffffffff808211156114a857600080fd5b818601915086601f8301126114bc57600080fd5b8135818111156114ce576114ce61145f565b8060051b604051601f19603f830116810181811085821117156114f3576114f361145f565b60405291825284820192508381018501918983111561151157600080fd5b938501935b8285101561153657611527856113c4565b84529385019392850192611516565b8096505050505050509250929050565b634e487b7160e01b600052601160045260246000fd5b6000821982111561156f5761156f611546565b500190565b60006020828403121561158657600080fd5b5051919050565b60008282101561159f5761159f611546565b500390565b600080604083850312156115b757600080fd5b505080516020909101519092909150565b60008160001904831182151516156115e2576115e2611546565b500290565b634e487b7160e01b600052601260045260246000fd5b60008261160c5761160c6115e7565b500490565b60006001820161162357611623611546565b5060010190565b60006020828403121561163c57600080fd5b81516111a5816113ac565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561166f57600080fd5b815180151581146111a557600080fd5b60008261168e5761168e6115e7565b500690565b6000825160005b818110156116b4576020818601810151858301520161169a565b818111156116c3576000828501525b50919091019291505056fea2646970667358221220391c6ba36ed7a0838351cb29f65ef69bdb21a946543fa092a63766f677c0f19c64736f6c634300080d0033a26469706673582212208175301b78d1f1faad1868a259495e78c78b3f8babeb632ca56b3b17b78dff0264736f6c634300080d0033
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.