Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Code
Read Contract
Write Contract
- Contract name:
- GaugeProxy
- Optimization enabled
- true
- Compiler version
- v0.6.12+commit.27d51765
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2022-04-28T20:14:18.565757Z
Constructor Arguments
a26469706673582212207c1d3daa559854f1aa1f1b8f989aab5ae29aa78d5222e29204fd5bd19640447a64736f6c634300060c00335361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a26469706673582212207c96e43c8276aa88598a3d8a1a58ba416cb4933659705ba0673aa31ab10b126464736f6c634300060c00336080604052670de0b6b3a764000060005534801561001c57600080fd5b50336000818152600260209081526040808320670de0b6b3a764000090819055815190815290517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36107678061007d6000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce567146101a557806370a08231146101c357806395d89b41146101e9578063a9059cbb146101f1578063dd62ed3e1461021d57610093565b806306fdde0314610098578063095ea7b31461011557806318160ddd1461015557806323b872dd1461016f575b600080fd5b6100a061024b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100da5781810151838201526020016100c2565b50505050905090810190601f1680156101075780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101416004803603604081101561012b57600080fd5b506001600160a01b038135169060200135610274565b604080519115158252519081900360200190f35b61015d6102da565b60408051918252519081900360200190f35b6101416004803603606081101561018557600080fd5b506001600160a01b038135811691602081013590911690604001356102e0565b6101ad6103c2565b6040805160ff9092168252519081900360200190f35b61015d600480360360208110156101d957600080fd5b50356001600160a01b03166103c7565b6100a06103e2565b6101416004803603604081101561020757600080fd5b506001600160a01b038135169060200135610405565b61015d6004803603604081101561023357600080fd5b506001600160a01b038135811691602001351661041b565b6040518060400160405280600d81526020016c4d617374657220435245414d5960981b81525081565b3360008181526001602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b60005481565b6001600160a01b03831660008181526001602090815260408083203380855292528220549192909190821480159061031a57506000198114155b156103ab5760006103468560405180606001604052806027815260200161070b60279139849190610446565b6001600160a01b0380891660008181526001602090815260408083209489168084529482529182902085905581518581529151949550929391927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92592918290030190a3505b6103b68686866104dd565b50600195945050505050565b601281565b6001600160a01b031660009081526002602052604090205490565b604051806040016040528060078152602001666d435245414d5960c81b81525081565b60006104123384846104dd565b50600192915050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600081848411156104d55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561049a578181015183820152602001610482565b50505050905090810190601f1680156104c75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b038316610538576040805162461bcd60e51b815260206004820152601d60248201527f5f7472616e73666572546f6b656e733a207a65726f2061646472657373000000604482015290519081900360640190fd5b6001600160a01b038216610593576040805162461bcd60e51b815260206004820152601d60248201527f5f7472616e73666572546f6b656e733a207a65726f2061646472657373000000604482015290519081900360640190fd5b60408051808201825260208082527f5f7472616e73666572546f6b656e733a20657863656564732062616c616e6365818301526001600160a01b0386166000908152600290915291909120546105ea918390610446565b6001600160a01b0380851660009081526002602081815260408084209590955584518086018652601a81527f5f7472616e73666572546f6b656e733a206f766572666c6f77730000000000008183015293871683525291909120546106509183906106ac565b6001600160a01b0380841660008181526002602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600083830182858210156107015760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561049a578181015183820152602001610482565b5094935050505056fe7472616e7366657246726f6d3a2065786365656473207370656e64657220616c6c6f77616e6365a264697066735822122066dfb077122e308b9dbb315d80ccbd9d03c39e61d81280b6de797cf6dfa8c66364736f6c634300060c0033000000000000000000000000063a5e4cd5e15ac66ea47134eb60e6b30a51b2bf0000000000000000000000001eca2c766072534dfee8793e54dc5b45d93a3e67000000000000000000000000e1e1b4582760fca9664d725412165c7cf04f5f44
Arg [0] (address) : 0x3daa559854f1aa1f1b8f989aab5ae29aa78d5222
Arg [1] (address) : 0x6f6c634300060c00335361666545524332303a20
Arg [2] (address) : 0x696f6e20646964206e6f74207375636365656453
Contract source code
// Forked from Pickle Finance at commit d2de3b9 // SPDX-License-Identifier: MIT pragma solidity ^0.6.12; library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "add: +"); return c; } function add( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, errorMessage); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "sub: -"); } function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "mul: *"); return c; } function mul( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, errorMessage); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "div: /"); } function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } } library Address { function isContract(address account) internal view returns (bool) { bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != 0x0 && codehash != accountHash); } function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } function sendValue(address payable recipient, uint256 amount) internal { require( address(this).balance >= amount, "Address: insufficient balance" ); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call{value: amount}(""); require( success, "Address: unable to send value, recipient may have reverted" ); } } interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); } library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { callOptionalReturn( token, abi.encodeWithSelector(token.transfer.selector, to, value) ); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { callOptionalReturn( token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value) ); } function safeApprove( IERC20 token, address spender, uint256 value ) internal { require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); callOptionalReturn( token, abi.encodeWithSelector(token.approve.selector, spender, value) ); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).add( value ); callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender).sub( value, "SafeERC20: decreased allowance below zero" ); callOptionalReturn( token, abi.encodeWithSelector( token.approve.selector, spender, newAllowance ) ); } function callOptionalReturn(IERC20 token, bytes memory data) private { require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require( abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed" ); } } } library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2); } } /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() public { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } contract Gauge is ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 public immutable MILKY; IERC20 public immutable CREAMY; IERC20 public immutable TOKEN; address public immutable DISTRIBUTION; uint256 public constant DURATION = 7 days; uint256 public periodFinish = 0; uint256 public rewardRate = 0; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; modifier onlyDistribution() { require( msg.sender == DISTRIBUTION, "Caller is not RewardsDistribution contract" ); _; } mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public rewards; uint256 private _totalSupply; uint256 public derivedSupply; mapping(address => uint256) private _balances; mapping(address => uint256) public derivedBalances; mapping(address => uint256) private _base; constructor( address _token, address _milky, address _creamy ) public { TOKEN = IERC20(_token); DISTRIBUTION = msg.sender; MILKY = IERC20(_milky); CREAMY = IERC20(_creamy); } function totalSupply() external view returns (uint256) { return _totalSupply; } function balanceOf(address account) external view returns (uint256) { return _balances[account]; } function lastTimeRewardApplicable() public view returns (uint256) { return Math.min(block.timestamp, periodFinish); } function rewardPerToken() public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add( lastTimeRewardApplicable() .sub(lastUpdateTime) .mul(rewardRate) .mul(1e18) .div(derivedSupply) ); } function derivedBalance(address account) public view returns (uint256) { uint256 _balance = _balances[account]; uint256 _derived = _balance.mul(40).div(100); uint256 _adjusted = ( _totalSupply.mul(CREAMY.balanceOf(account)).div( CREAMY.totalSupply() ) ).mul(60).div(100); return Math.min(_derived.add(_adjusted), _balance); } function kick(address account) public { uint256 _derivedBalance = derivedBalances[account]; derivedSupply = derivedSupply.sub(_derivedBalance); _derivedBalance = derivedBalance(account); derivedBalances[account] = _derivedBalance; derivedSupply = derivedSupply.add(_derivedBalance); } function earned(address account) public view returns (uint256) { return derivedBalances[account] .mul(rewardPerToken().sub(userRewardPerTokenPaid[account])) .div(1e18) .add(rewards[account]); } function getRewardForDuration() external view returns (uint256) { return rewardRate.mul(DURATION); } function depositAll() external { _deposit(TOKEN.balanceOf(msg.sender), msg.sender); } function deposit(uint256 amount) external { _deposit(amount, msg.sender); } function depositFor(uint256 amount, address account) external { _deposit(amount, account); } function _deposit(uint256 amount, address account) internal nonReentrant updateReward(account) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Staked(account, amount); TOKEN.safeTransferFrom(account, address(this), amount); } function withdrawAll() external { _withdraw(_balances[msg.sender]); } function withdraw(uint256 amount) external { _withdraw(amount); } function _withdraw(uint256 amount) internal nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); _totalSupply = _totalSupply.sub(amount); _balances[msg.sender] = _balances[msg.sender].sub(amount); TOKEN.safeTransfer(msg.sender, amount); emit Withdrawn(msg.sender, amount); } function getReward() public nonReentrant updateReward(msg.sender) { uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; MILKY.safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, reward); } } function exit() external { _withdraw(_balances[msg.sender]); getReward(); } function notifyRewardAmount(uint256 reward) external onlyDistribution updateReward(address(0)) { MILKY.safeTransferFrom(DISTRIBUTION, address(this), reward); if (block.timestamp >= periodFinish) { rewardRate = reward.div(DURATION); } else { uint256 remaining = periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardRate); rewardRate = reward.add(leftover).div(DURATION); } // Ensure the provided reward amount is not more than the balance in the contract. // This keeps the reward rate in the right range, preventing overflows due to // very high values of rewardRate in the earned and rewardsPerToken functions; // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. uint256 balance = MILKY.balanceOf(address(this)); require( rewardRate <= balance.div(DURATION), "Provided reward too high" ); lastUpdateTime = block.timestamp; periodFinish = block.timestamp.add(DURATION); emit RewardAdded(reward); } modifier updateReward(address account) { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } _; if (account != address(0)) { kick(account); } } event RewardAdded(uint256 reward); event Staked(address indexed user, uint256 amount); event Withdrawn(address indexed user, uint256 amount); event RewardPaid(address indexed user, uint256 reward); } interface MasterChef { function deposit(uint256, uint256) external; function withdraw(uint256, uint256) external; function userInfo(uint256, address) external view returns (uint256, uint256); } contract ProtocolGovernance { /// @notice governance address for the governance contract address public governance; address public pendingGovernance; /** * @notice Allows governance to change governance (for future upgradability) * @param _governance new governance address to set */ function setGovernance(address _governance) external { require(msg.sender == governance, "setGovernance: !gov"); pendingGovernance = _governance; } /** * @notice Allows pendingGovernance to accept their role as governance (protection pattern) */ function acceptGovernance() external { require( msg.sender == pendingGovernance, "acceptGovernance: !pendingGov" ); governance = pendingGovernance; } } contract MasterCreamy { using SafeMath for uint256; /// @notice EIP-20 token name for this token string public constant name = "Master CREAMY"; /// @notice EIP-20 token symbol for this token string public constant symbol = "mCREAMY"; /// @notice EIP-20 token decimals for this token uint8 public constant decimals = 18; /// @notice Total number of tokens in circulation uint256 public totalSupply = 1e18; mapping(address => mapping(address => uint256)) internal allowances; mapping(address => uint256) internal balances; /// @notice The standard EIP-20 transfer event event Transfer(address indexed from, address indexed to, uint256 amount); /// @notice The standard EIP-20 approval event event Approval( address indexed owner, address indexed spender, uint256 amount ); constructor() public { balances[msg.sender] = 1e18; emit Transfer(address(0x0), msg.sender, 1e18); } /** * @notice Get the number of tokens `spender` is approved to spend on behalf of `account` * @param account The address of the account holding the funds * @param spender The address of the account spending the funds * @return The number of tokens approved */ function allowance(address account, address spender) external view returns (uint256) { return allowances[account][spender]; } /** * @notice Approve `spender` to transfer up to `amount` from `src` * @dev This will overwrite the approval amount for `spender` * and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve) * @param spender The address of the account which may transfer tokens * @param amount The number of tokens that are approved (2^256-1 means infinite) * @return Whether or not the approval succeeded */ function approve(address spender, uint256 amount) external returns (bool) { allowances[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } /** * @notice Get the number of tokens held by the `account` * @param account The address of the account to get the balance of * @return The number of tokens held */ function balanceOf(address account) external view returns (uint256) { return balances[account]; } /** * @notice Transfer `amount` tokens from `msg.sender` to `dst` * @param dst The address of the destination account * @param amount The number of tokens to transfer * @return Whether or not the transfer succeeded */ function transfer(address dst, uint256 amount) external returns (bool) { _transferTokens(msg.sender, dst, amount); return true; } /** * @notice Transfer `amount` tokens from `src` to `dst` * @param src The address of the source account * @param dst The address of the destination account * @param amount The number of tokens to transfer * @return Whether or not the transfer succeeded */ function transferFrom( address src, address dst, uint256 amount ) external returns (bool) { address spender = msg.sender; uint256 spenderAllowance = allowances[src][spender]; if (spender != src && spenderAllowance != uint256(-1)) { uint256 newAllowance = spenderAllowance.sub( amount, "transferFrom: exceeds spender allowance" ); allowances[src][spender] = newAllowance; emit Approval(src, spender, newAllowance); } _transferTokens(src, dst, amount); return true; } function _transferTokens( address src, address dst, uint256 amount ) internal { require(src != address(0), "_transferTokens: zero address"); require(dst != address(0), "_transferTokens: zero address"); balances[src] = balances[src].sub( amount, "_transferTokens: exceeds balance" ); balances[dst] = balances[dst].add(amount, "_transferTokens: overflows"); emit Transfer(src, dst, amount); } } contract GaugeProxy is ProtocolGovernance { using SafeMath for uint256; using SafeERC20 for IERC20; MasterChef public immutable MASTER; IERC20 public immutable MILKY; IERC20 public immutable CREAMY; IERC20 public immutable TOKEN; uint256 public pid; uint256 public totalWeight; address[] internal _tokens; mapping(address => address) public gauges; // token => gauge mapping(address => uint256) public weights; // token => weight mapping(address => mapping(address => uint256)) public votes; // msg.sender => votes mapping(address => address[]) public tokenVote; // msg.sender => token mapping(address => uint256) public usedWeights; // msg.sender => total voting weight of user function tokens() external view returns (address[] memory) { return _tokens; } function getGauge(address _token) external view returns (address) { return gauges[_token]; } constructor( address _milky, address _creamy, address _master ) public { TOKEN = IERC20(address(new MasterCreamy())); governance = msg.sender; MILKY = IERC20(_milky); CREAMY = IERC20(_creamy); MASTER = MasterChef(_master); } // Reset votes to 0 function reset() external { _reset(msg.sender); } // Reset votes to 0 function _reset(address _owner) internal { address[] storage _tokenVote = tokenVote[_owner]; uint256 _tokenVoteCnt = _tokenVote.length; for (uint256 i = 0; i < _tokenVoteCnt; i++) { address _token = _tokenVote[i]; uint256 _votes = votes[_owner][_token]; if (_votes > 0) { totalWeight = totalWeight.sub(_votes); weights[_token] = weights[_token].sub(_votes); votes[_owner][_token] = 0; } } delete tokenVote[_owner]; } // Adjusts _owner's votes according to latest _owner's CREAMY balance function poke(address _owner) public { address[] memory _tokenVote = tokenVote[_owner]; uint256 _tokenCnt = _tokenVote.length; uint256[] memory _weights = new uint256[](_tokenCnt); uint256 _prevUsedWeight = usedWeights[_owner]; uint256 _weight = CREAMY.balanceOf(_owner); for (uint256 i = 0; i < _tokenCnt; i++) { uint256 _prevWeight = votes[_owner][_tokenVote[i]]; _weights[i] = _prevWeight.mul(_weight).div(_prevUsedWeight); } _vote(_owner, _tokenVote, _weights); } function _vote( address _owner, address[] memory _tokenVote, uint256[] memory _weights ) internal { // _weights[i] = percentage * 100 _reset(_owner); uint256 _tokenCnt = _tokenVote.length; uint256 _weight = CREAMY.balanceOf(_owner); uint256 _totalVoteWeight = 0; uint256 _usedWeight = 0; for (uint256 i = 0; i < _tokenCnt; i++) { _totalVoteWeight = _totalVoteWeight.add(_weights[i]); } for (uint256 i = 0; i < _tokenCnt; i++) { address _token = _tokenVote[i]; address _gauge = gauges[_token]; uint256 _tokenWeight = _weights[i].mul(_weight).div( _totalVoteWeight ); if (_gauge != address(0x0)) { _usedWeight = _usedWeight.add(_tokenWeight); totalWeight = totalWeight.add(_tokenWeight); weights[_token] = weights[_token].add(_tokenWeight); tokenVote[_owner].push(_token); votes[_owner][_token] = _tokenWeight; } } usedWeights[_owner] = _usedWeight; } // Vote with CREAMY on a gauge function vote(address[] calldata _tokenVote, uint256[] calldata _weights) external { require(_tokenVote.length == _weights.length); _vote(msg.sender, _tokenVote, _weights); } // Add new token gauge function addGauge(address _token) external { require(msg.sender == governance, "!gov"); require(gauges[_token] == address(0x0), "exists"); gauges[_token] = address( new Gauge(_token, address(MILKY), address(CREAMY)) ); _tokens.push(_token); } // Sets MasterChef PID function setPID(uint256 _pid) external { require(msg.sender == governance, "!gov"); require(pid == 0, "pid has already been set"); require(_pid > 0, "invalid pid"); pid = _pid; } // Deposits mCREAMY into MasterChef function deposit() public { require(pid > 0, "pid not initialized"); IERC20 _token = TOKEN; uint256 _balance = _token.balanceOf(address(this)); _token.safeApprove(address(MASTER), 0); _token.safeApprove(address(MASTER), _balance); MASTER.deposit(pid, _balance); } // Fetches Milky function collect() public { (uint256 _locked, ) = MASTER.userInfo(pid, address(this)); MASTER.withdraw(pid, _locked); deposit(); } function length() external view returns (uint256) { return _tokens.length; } function distribute() external { collect(); uint256 _balance = MILKY.balanceOf(address(this)); if (_balance > 0 && totalWeight > 0) { for (uint256 i = 0; i < _tokens.length; i++) { address _token = _tokens[i]; address _gauge = gauges[_token]; uint256 _reward = _balance.mul(weights[_token]).div( totalWeight ); if (_reward > 0) { MILKY.safeApprove(_gauge, 0); MILKY.safeApprove(_gauge, _reward); Gauge(_gauge).notifyRewardAmount(_reward); } } } } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_milky","internalType":"address"},{"type":"address","name":"_creamy","internalType":"address"},{"type":"address","name":"_master","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"CREAMY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract MasterChef"}],"name":"MASTER","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"MILKY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"TOKEN","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptGovernance","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addGauge","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"collect","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"deposit","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"distribute","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"gauges","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getGauge","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"length","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingGovernance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pid","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"poke","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"reset","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setGovernance","inputs":[{"type":"address","name":"_governance","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPID","inputs":[{"type":"uint256","name":"_pid","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"tokenVote","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"tokens","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalWeight","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"usedWeights","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"vote","inputs":[{"type":"address[]","name":"_tokenVote","internalType":"address[]"},{"type":"uint256[]","name":"_weights","internalType":"uint256[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"votes","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"weights","inputs":[{"type":"address","name":"","internalType":"address"}]}]
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061018d5760003560e01c8063ab033ea9116100de578063d0e30db011610097578063e522538111610071578063e522538114610489578063f106845414610491578063f2a1a8ed14610499578063f39c38a0146104c55761018d565b8063d0e30db014610471578063d826f88f14610479578063e4fc6b6d146104815761018d565b8063ab033ea9146103a3578063b1a997ac146103c9578063b1c6f0e9146103ef578063b9a09fd514610415578063cad1b9061461043b578063ce9a2517146104695761018d565b806382bfefc81161014b5780639d63848a116101255780639d63848a146102f75780639da882ac1461034f5780639dba14ec14610375578063a7cac8461461037d5761018d565b806382bfefc8146102ca5780638d060519146102d257806396c82e57146102ef5761018d565b80622f8de4146101925780631f7b6d32146101ca578063238efcbc146101d2578063471aedc2146101dc5780635aa6e675146102005780636f816a2014610208575b600080fd5b6101b8600480360360208110156101a857600080fd5b50356001600160a01b03166104cd565b60408051918252519081900360200190f35b6101b86104df565b6101da6104e5565b005b6101e4610568565b604080516001600160a01b039092168252519081900360200190f35b6101e461058c565b6101da6004803603604081101561021e57600080fd5b81019060208101813564010000000081111561023957600080fd5b82018360208201111561024b57600080fd5b8035906020019184602083028401116401000000008311171561026d57600080fd5b91939092909160208101903564010000000081111561028b57600080fd5b82018360208201111561029d57600080fd5b803590602001918460208302840111640100000000831117156102bf57600080fd5b50909250905061059b565b6101e461061b565b6101da600480360360208110156102e857600080fd5b503561063f565b6101b8610724565b6102ff61072a565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561033b578181015183820152602001610323565b505050509050019250505060405180910390f35b6101da6004803603602081101561036557600080fd5b50356001600160a01b031661078c565b6101e4610924565b6101b86004803603602081101561039357600080fd5b50356001600160a01b0316610948565b6101da600480360360208110156103b957600080fd5b50356001600160a01b031661095a565b6101da600480360360208110156103df57600080fd5b50356001600160a01b03166109d1565b6101e46004803603602081101561040557600080fd5b50356001600160a01b0316610be6565b6101e46004803603602081101561042b57600080fd5b50356001600160a01b0316610c04565b6101b86004803603604081101561045157600080fd5b506001600160a01b0381358116916020013516610c1f565b6101e4610c3c565b6101da610c60565b6101da610e33565b6101da610e3e565b6101da61103e565b6101b861116f565b6101e4600480360360408110156104af57600080fd5b506001600160a01b038135169060200135611175565b6101e46111aa565b60096020526000908152604090205481565b60045490565b6001546001600160a01b03163314610544576040805162461bcd60e51b815260206004820152601d60248201527f616363657074476f7665726e616e63653a202170656e64696e67476f76000000604482015290519081900360640190fd5b600154600080546001600160a01b0319166001600160a01b03909216919091179055565b7f000000000000000000000000e1e1b4582760fca9664d725412165c7cf04f5f4481565b6000546001600160a01b031681565b8281146105a757600080fd5b61061533858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208089028281018201909352888252909350889250879182918501908490808284376000920191909152506111b992505050565b50505050565b7f000000000000000000000000077142c95951e5d248f6e232ed59ce014987c99281565b6000546001600160a01b03163314610687576040805162461bcd60e51b8152602060048083019190915260248201526310b3b7bb60e11b604482015290519081900360640190fd5b600254156106dc576040805162461bcd60e51b815260206004820152601860248201527f7069642068617320616c7265616479206265656e207365740000000000000000604482015290519081900360640190fd5b6000811161071f576040805162461bcd60e51b815260206004820152600b60248201526a1a5b9d985b1a59081c1a5960aa1b604482015290519081900360640190fd5b600255565b60035481565b6060600480548060200260200160405190810160405280929190818152602001828054801561078257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610764575b5050505050905090565b6000546001600160a01b031633146107d4576040805162461bcd60e51b8152602060048083019190915260248201526310b3b7bb60e11b604482015290519081900360640190fd5b6001600160a01b03818116600090815260056020526040902054161561082a576040805162461bcd60e51b815260206004820152600660248201526565786973747360d01b604482015290519081900360640190fd5b807f000000000000000000000000063a5e4cd5e15ac66ea47134eb60e6b30a51b2bf7f0000000000000000000000001eca2c766072534dfee8793e54dc5b45d93a3e67604051610879906119f4565b6001600160a01b03938416815291831660208301529091166040808301919091525190819003606001906000f0801580156108b8573d6000803e3d6000fd5b506001600160a01b0391821660008181526005602052604081208054939094166001600160a01b0319938416179093556004805460018101825593527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b90920180549091169091179055565b7f0000000000000000000000001eca2c766072534dfee8793e54dc5b45d93a3e6781565b60066020526000908152604090205481565b6000546001600160a01b031633146109af576040805162461bcd60e51b815260206004820152601360248201527239b2ba23b7bb32b93730b731b29d1010b3b7bb60691b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b038116600090815260086020908152604091829020805483518184028101840190945280845260609392830182828015610a3b57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a1d575b5050505050905060008151905060608167ffffffffffffffff81118015610a6157600080fd5b50604051908082528060200260200182016040528015610a8b578160200160208202803683370190505b506001600160a01b0380861660008181526009602090815260408083205481516370a0823160e01b8152600481019590955290519596509491937f0000000000000000000000001eca2c766072534dfee8793e54dc5b45d93a3e6716926370a082319260248083019392829003018186803b158015610b0957600080fd5b505afa158015610b1d573d6000803e3d6000fd5b505050506040513d6020811015610b3357600080fd5b5051905060005b84811015610bd2576001600160a01b038716600090815260076020526040812087518290899085908110610b6a57fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020549050610bb284610bac85846113f090919063ffffffff16565b90611451565b858381518110610bbe57fe5b602090810291909101015250600101610b3a565b50610bde8686856111b9565b505050505050565b6001600160a01b039081166000908152600560205260409020541690565b6005602052600090815260409020546001600160a01b031681565b600760209081526000928352604080842090915290825290205481565b7f000000000000000000000000063a5e4cd5e15ac66ea47134eb60e6b30a51b2bf81565b600060025411610cad576040805162461bcd60e51b81526020600482015260136024820152721c1a59081b9bdd081a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b604080516370a0823160e01b815230600482015290517f000000000000000000000000077142c95951e5d248f6e232ed59ce014987c992916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b158015610d1857600080fd5b505afa158015610d2c573d6000803e3d6000fd5b505050506040513d6020811015610d4257600080fd5b50519050610d7b6001600160a01b0383167f000000000000000000000000e1e1b4582760fca9664d725412165c7cf04f5f44600061147c565b610daf6001600160a01b0383167f000000000000000000000000e1e1b4582760fca9664d725412165c7cf04f5f448361147c565b7f000000000000000000000000e1e1b4582760fca9664d725412165c7cf04f5f446001600160a01b031663e2bbb158600254836040518363ffffffff1660e01b81526004018083815260200182815260200192505050600060405180830381600087803b158015610e1f57600080fd5b505af1158015610bde573d6000803e3d6000fd5b610e3c33611594565b565b610e4661103e565b60007f000000000000000000000000063a5e4cd5e15ac66ea47134eb60e6b30a51b2bf6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610eb557600080fd5b505afa158015610ec9573d6000803e3d6000fd5b505050506040513d6020811015610edf57600080fd5b505190508015801590610ef457506000600354115b1561103b5760005b60045481101561103957600060048281548110610f1557fe5b60009182526020808320909101546001600160a01b03908116808452600583526040808520546003546006909552908520549195509091169291610f5e91610bac9088906113f0565b9050801561102e57610f9b6001600160a01b037f000000000000000000000000063a5e4cd5e15ac66ea47134eb60e6b30a51b2bf1683600061147c565b610fcf6001600160a01b037f000000000000000000000000063a5e4cd5e15ac66ea47134eb60e6b30a51b2bf16838361147c565b816001600160a01b0316633c6b16ab826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561101557600080fd5b505af1158015611029573d6000803e3d6000fd5b505050505b505050600101610efc565b505b50565b600254604080516393f1a40b60e01b8152600481019290925230602483015280516000926001600160a01b037f000000000000000000000000e1e1b4582760fca9664d725412165c7cf04f5f4416926393f1a40b92604480840193829003018186803b1580156110ad57600080fd5b505afa1580156110c1573d6000803e3d6000fd5b505050506040513d60408110156110d757600080fd5b505160025460408051630441a3e760e41b8152600481019290925260248201839052519192506001600160a01b037f000000000000000000000000e1e1b4582760fca9664d725412165c7cf04f5f44169163441a3e709160448082019260009290919082900301818387803b15801561114f57600080fd5b505af1158015611163573d6000803e3d6000fd5b5050505061103b610c60565b60025481565b6008602052816000526040600020818154811061118e57fe5b6000918252602090912001546001600160a01b03169150829050565b6001546001600160a01b031681565b6111c283611594565b8151604080516370a0823160e01b81526001600160a01b03868116600483015291516000927f0000000000000000000000001eca2c766072534dfee8793e54dc5b45d93a3e6716916370a08231916024808301926020929190829003018186803b15801561122f57600080fd5b505afa158015611243573d6000803e3d6000fd5b505050506040513d602081101561125957600080fd5b50519050600080805b8481101561129a5761129086828151811061127957fe5b60200260200101518461169690919063ffffffff16565b9250600101611262565b5060005b848110156113cb5760008782815181106112b457fe5b6020908102919091018101516001600160a01b038082166000908152600590935260408320548a51929450169190611310908790610bac908a908d90899081106112fa57fe5b60200260200101516113f090919063ffffffff16565b90506001600160a01b038216156113c05761132b8582611696565b60035490955061133b9082611696565b6003556001600160a01b0383166000908152600660205260409020546113619082611696565b6001600160a01b03808516600081815260066020908152604080832095909555928f168082526008845284822080546001810182559083528483200180546001600160a01b031916841790558152600783528381209181529152208190555b50505060010161129e565b506001600160a01b039096166000908152600960205260409020959095555050505050565b6000826113ff5750600061144b565b8282028284828161140c57fe5b0414611448576040805162461bcd60e51b815260206004820152600660248201526536bab61d101560d11b604482015290519081900360640190fd5b90505b92915050565b60006114488383604051806040016040528060068152602001656469763a202f60d01b8152506116d9565b801580611502575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b1580156114d457600080fd5b505afa1580156114e8573d6000803e3d6000fd5b505050506040513d60208110156114fe57600080fd5b5051155b61153d5760405162461bcd60e51b81526004018080602001828103825260368152602001806131756036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261158f90849061177b565b505050565b6001600160a01b0381166000908152600860205260408120805490915b818110156116745760008382815481106115c757fe5b60009182526020808320909101546001600160a01b03888116845260078352604080852091909216808552925290912054909150801561166a5760035461160e9082611933565b6003556001600160a01b0382166000908152600660205260409020546116349082611933565b6001600160a01b03808416600081815260066020908152604080832095909555928a168152600783528381209181529152908120555b50506001016115b1565b506001600160a01b038316600090815260086020526040812061158f91611a01565b600082820183811015611448576040805162461bcd60e51b81526020600482015260066024820152656164643a202b60d01b604482015290519081900360640190fd5b600081836117655760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561172a578181015183820152602001611712565b50505050905090810190601f1680156117575780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161177157fe5b0495945050505050565b61178d826001600160a01b031661195e565b6117de576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061181c5780518252601f1990920191602091820191016117fd565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461187e576040519150601f19603f3d011682016040523d82523d6000602084013e611883565b606091505b5091509150816118da576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610615578080602001905160208110156118f657600080fd5b50516106155760405162461bcd60e51b815260040180806020018281038252602a81526020018061314b602a913960400191505060405180910390fd5b60006114488383604051806040016040528060068152602001657375623a202d60d01b81525061199a565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906119925750808214155b949350505050565b600081848411156119ec5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561172a578181015183820152602001611712565b505050900390565b61171780611a3483390190565b508054600082559060005260206000209081019061103b91905b80821115611a2f5760008155600101611a1b565b509056fe6101006040526000600155600060025534801561001b57600080fd5b506040516117173803806117178339818101604052606081101561003e57600080fd5b508051602082015160409092015160016000556001600160601b0319606092831b811660c05233831b60e05292821b8316608052901b1660a05260805160601c60a05160601c60c05160601c60e05160601c61162c6100eb600039806104fb52806105e2528061096a52508061099c5280610c7f5280610f85528061119b525080610a515280610b325280610bdb5250806105c0528061066c52806108ae5280610ad3525061162c6000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c806382bfefc811610104578063cd3daf9d116100a2578063de5f626811610071578063de5f626814610400578063df136d6514610408578063e9fad8ee14610410578063ebe2b12b14610418576101ce565b8063cd3daf9d146103c2578063ce9a2517146103ca578063d35e2544146103d2578063d7da4bb0146103f8576101ce565b806396c55175116100de57806396c551751461036f5780639dba14ec14610395578063b6b55f251461039d578063c8f33c91146103ba576101ce565b806382bfefc814610339578063853828b6146103415780638b87634714610349576101ce565b80633c6b16ab1161017157806370a082311161014b57806370a08231146102df5780637b0a47ee146103055780637c91e4eb1461030d57806380faa57d14610331576101ce565b80633c6b16ab146102945780633d18b912146102b157806363fb415b146102b9576101ce565b80631be05289116101ad5780631be05289146102395780631c1f78eb146102415780632e1a7d4d1461024957806336efd16f14610268576101ce565b80628cc262146101d35780630700037d1461020b57806318160ddd14610231575b600080fd5b6101f9600480360360208110156101e957600080fd5b50356001600160a01b0316610420565b60408051918252519081900360200190f35b6101f96004803603602081101561022157600080fd5b50356001600160a01b031661049e565b6101f96104b0565b6101f96104b7565b6101f96104be565b6102666004803603602081101561025f57600080fd5b50356104d6565b005b6102666004803603604081101561027e57600080fd5b50803590602001356001600160a01b03166104e2565b610266600480360360208110156102aa57600080fd5b50356104f0565b6102666107ca565b6101f9600480360360208110156102cf57600080fd5b50356001600160a01b0316610935565b6101f9600480360360208110156102f557600080fd5b50356001600160a01b0316610947565b6101f9610962565b610315610968565b604080516001600160a01b039092168252519081900360200190f35b6101f961098c565b61031561099a565b6102666109be565b6101f96004803603602081101561035f57600080fd5b50356001600160a01b03166109d9565b6102666004803603602081101561038557600080fd5b50356001600160a01b03166109eb565b610315610a4f565b610266600480360360208110156103b357600080fd5b5035610a73565b6101f9610a7d565b6101f9610a83565b610315610ad1565b6101f9600480360360208110156103e857600080fd5b50356001600160a01b0316610af5565b6101f9610c74565b610266610c7a565b6101f9610d1c565b610266610d22565b6101f9610d43565b6001600160a01b0381166000908152600660209081526040808320546005909252822054610498919061049290670de0b6b3a76400009061048c9061046d90610467610a83565b90610d49565b6001600160a01b0388166000908152600a602052604090205490610d7b565b90610dd3565b90610dfe565b92915050565b60066020526000908152604090205481565b6007545b90565b62093a8081565b6002546000906104d19062093a80610d7b565b905090565b6104df81610e41565b50565b6104ec828261100b565b5050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105575760405162461bcd60e51b815260040180806020018281038252602a8152602001806115a3602a913960400191505060405180910390fd5b6000610561610a83565b60045561056c61098c565b6003556001600160a01b038116156105b35761058781610420565b6001600160a01b0382166000908152600660209081526040808320939093556004546005909152919020555b6106086001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000030856111e5565b60015442106106265761061e8262093a80610dd3565b600255610668565b6001546000906106369042610d49565b9050600061064f60025483610d7b90919063ffffffff16565b905061066262093a8061048c8684610dfe565b60025550505b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156106d757600080fd5b505afa1580156106eb573d6000803e3d6000fd5b505050506040513d602081101561070157600080fd5b505190506107128162093a80610dd3565b6002541115610768576040805162461bcd60e51b815260206004820152601860248201527f50726f76696465642072657761726420746f6f20686967680000000000000000604482015290519081900360640190fd5b42600381905561077b9062093a80610dfe565b6001556040805184815290517fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9181900360200190a1506001600160a01b038116156104ec576104ec816109eb565b60026000541415610822576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005533610830610a83565b60045561083b61098c565b6003556001600160a01b038116156108825761085681610420565b6001600160a01b0382166000908152600660209081526040808320939093556004546005909152919020555b33600090815260066020526040902054801561091457336000818152600660205260408120556108dd907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169083611245565b60408051828152905133917fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486919081900360200190a25b506001600160a01b0381161561092d5761092d816109eb565b506001600055565b600a6020526000908152604090205481565b6001600160a01b031660009081526009602052604090205490565b60025481565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006104d14260015461129c565b7f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600960205260409020546109d790610e41565b565b60056020526000908152604090205481565b6001600160a01b0381166000908152600a6020526040902054600854610a119082610d49565b600855610a1d82610af5565b6001600160a01b0383166000908152600a60205260409020819055600854909150610a489082610dfe565b6008555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6104df813361100b565b60035481565b600060075460001415610a9957506004546104b4565b6104d1610ac860085461048c670de0b6b3a7640000610ac2600254610ac260035461046761098c565b90610d7b565b60045490610dfe565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001600160a01b03811660009081526009602052604081205481610b1f606461048c846028610d7b565b90506000610c56606461048c603c610ac27f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b8957600080fd5b505afa158015610b9d573d6000803e3d6000fd5b505050506040513d6020811015610bb357600080fd5b5051604080516370a0823160e01b81526001600160a01b038d81166004830152915161048c927f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b158015610c2157600080fd5b505afa158015610c35573d6000803e3d6000fd5b505050506040513d6020811015610c4b57600080fd5b505160075490610d7b565b9050610c6b610c658383610dfe565b8461129c565b95945050505050565b60085481565b6109d77f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610cea57600080fd5b505afa158015610cfe573d6000803e3d6000fd5b505050506040513d6020811015610d1457600080fd5b50513361100b565b60045481565b33600090815260096020526040902054610d3b90610e41565b6109d76107ca565b60015481565b6000610d748383604051806040016040528060068152602001657375623a202d60d01b8152506112b2565b9392505050565b600082610d8a57506000610498565b82820282848281610d9757fe5b0414610d74576040805162461bcd60e51b815260206004820152600660248201526536bab61d101560d11b604482015290519081900360640190fd5b6000610d748383604051806040016040528060068152602001656469763a202f60d01b815250611349565b600082820183811015610d74576040805162461bcd60e51b81526020600482015260066024820152656164643a202b60d01b604482015290519081900360640190fd5b60026000541415610e99576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005533610ea7610a83565b600455610eb261098c565b6003556001600160a01b03811615610ef957610ecd81610420565b6001600160a01b0382166000908152600660209081526040808320939093556004546005909152919020555b60008211610f42576040805162461bcd60e51b8152602060048201526011602482015270043616e6e6f74207769746864726177203607c1b604482015290519081900360640190fd5b600754610f4f9083610d49565b60075533600090815260096020526040902054610f6c9083610d49565b33600081815260096020526040902091909155610fb4907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169084611245565b60408051838152905133917f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5919081900360200190a26001600160a01b0381161561100257611002816109eb565b50506001600055565b60026000541415611063576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260005580611071610a83565b60045561107c61098c565b6003556001600160a01b038116156110c35761109781610420565b6001600160a01b0382166000908152600660209081526040808320939093556004546005909152919020555b60008311611109576040805162461bcd60e51b815260206004820152600e60248201526d043616e6e6f74207374616b6520360941b604482015290519081900360640190fd5b6007546111169084610dfe565b6007556001600160a01b03821660009081526009602052604090205461113c9084610dfe565b6001600160a01b038316600081815260096020908152604091829020939093558051868152905191927f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d92918290030190a26111c36001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168330866111e5565b6001600160a01b038116156111db576111db816109eb565b5050600160005550565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261123f9085906113ae565b50505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526112979084906113ae565b505050565b60008183106112ab5781610d74565b5090919050565b600081848411156113415760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156113065781810151838201526020016112ee565b50505050905090810190601f1680156113335780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836113985760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156113065781810151838201526020016112ee565b5060008385816113a457fe5b0495945050505050565b6113c0826001600160a01b0316611566565b611411576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b6020831061144f5780518252601f199092019160209182019101611430565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146114b1576040519150601f19603f3d011682016040523d82523d6000602084013e6114b6565b606091505b50915091508161150d576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561123f5780806020019051602081101561152957600080fd5b505161123f5760405162461bcd60e51b815260040180806020018281038252602a8152602001806115cd602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470811580159061159a5750808214155b94935050505056fe43616c6c6572206973206e6f742052657761726473446973747269627574696f6e20636f6e74726163745361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212207c1d3daa559854f1aa1f1b8f989aab5ae29aa78d5222e29204fd5bd19640447a64736f6c634300060c00335361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e6365a26469706673582212207c96e43c8276aa88598a3d8a1a58ba416cb4933659705ba0673aa31ab10b126464736f6c634300060c0033