Address Details
contract
0x572564B0efEC39Dd325138187F5DD4e75B17251E
- Contract Name
- StakingRewards
- Creator
- 0x9ee360–7a65d2 at 0x326c20–38c74d
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- 14,703 Transactions
- Transfers
- 15,287 Transfers
- Gas Used
- 1,175,014,932
- Last Balance Update
- 12840156
Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- StakingRewards
- Optimization enabled
- true
- Compiler version
- v0.8.3+commit.8d00100c
- Optimization runs
- 999999
- EVM Version
- istanbul
- Verified at
- 2021-05-02T20:52:29.209587Z
Contract source code
// SPDX-License-Identifier: MIT // solhint-disable not-rely-on-time pragma solidity ^0.8.3; import "../../openzeppelin-solidity/contracts/Math.sol"; import "../../openzeppelin-solidity/contracts/SafeMath.sol"; import "../../openzeppelin-solidity/contracts/SafeERC20.sol"; import "../../openzeppelin-solidity/contracts/ReentrancyGuard.sol"; // Inheritance import "./interfaces/IStakingRewards.sol"; import "./RewardsDistributionRecipient.sol"; // https://docs.synthetix.io/contracts/source/contracts/stakingrewards // XXX: removed Pausable contract StakingRewards is IStakingRewards, RewardsDistributionRecipient, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; /* ========== STATE VARIABLES ========== */ IERC20 public rewardsToken; IERC20 public stakingToken; uint256 public periodFinish = 0; uint256 public rewardRate = 0; uint256 public rewardsDuration = 7 days; uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public rewards; uint256 private _totalSupply; mapping(address => uint256) private _balances; /* ========== CONSTRUCTOR ========== */ constructor( address _owner, address _rewardsDistribution, address _rewardsToken, address _stakingToken ) Owned(_owner) { rewardsToken = IERC20(_rewardsToken); stakingToken = IERC20(_stakingToken); rewardsDistribution = _rewardsDistribution; } /* ========== VIEWS ========== */ function totalSupply() external view override returns (uint256) { return _totalSupply; } function balanceOf(address account) external view override returns (uint256) { return _balances[account]; } function lastTimeRewardApplicable() public view override returns (uint256) { return Math.min(block.timestamp, periodFinish); } function rewardPerToken() public view override returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored.add( lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalSupply) ); } function earned(address account) public view override returns (uint256) { return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]); } function getRewardForDuration() external view override returns (uint256) { return rewardRate.mul(rewardsDuration); } /* ========== MUTATIVE FUNCTIONS ========== */ // XXX: removed notPaused function stake(uint256 amount) external override nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply = _totalSupply.add(amount); _balances[msg.sender] = _balances[msg.sender].add(amount); stakingToken.safeTransferFrom(msg.sender, address(this), amount); emit Staked(msg.sender, amount); } function withdraw(uint256 amount) public override nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); _totalSupply = _totalSupply.sub(amount); _balances[msg.sender] = _balances[msg.sender].sub(amount); stakingToken.safeTransfer(msg.sender, amount); emit Withdrawn(msg.sender, amount); } function getReward() public override nonReentrant updateReward(msg.sender) { uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; rewardsToken.safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, reward); } } function exit() external override { withdraw(_balances[msg.sender]); getReward(); } /* ========== RESTRICTED FUNCTIONS ========== */ function notifyRewardAmount(uint256 reward) external override onlyRewardsDistribution updateReward(address(0)) { if (block.timestamp >= periodFinish) { rewardRate = reward.div(rewardsDuration); } else { uint256 remaining = periodFinish.sub(block.timestamp); uint256 leftover = remaining.mul(rewardRate); rewardRate = reward.add(leftover).div(rewardsDuration); } // 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. uint balance = rewardsToken.balanceOf(address(this)); require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high"); lastUpdateTime = block.timestamp; periodFinish = block.timestamp.add(rewardsDuration); emit RewardAdded(reward); } // End rewards emission earlier function updatePeriodFinish(uint timestamp) external onlyOwner updateReward(address(0)) { periodFinish = timestamp; } // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner { require(tokenAddress != address(stakingToken), "Cannot withdraw the staking token"); IERC20(tokenAddress).safeTransfer(owner, tokenAmount); emit Recovered(tokenAddress, tokenAmount); } function setRewardsDuration(uint256 _rewardsDuration) external onlyOwner { require( block.timestamp > periodFinish, "Previous rewards period must be complete before changing the duration for the new period" ); rewardsDuration = _rewardsDuration; emit RewardsDurationUpdated(rewardsDuration); } /* ========== MODIFIERS ========== */ modifier updateReward(address account) { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = lastTimeRewardApplicable(); if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } _; } /* ========== EVENTS ========== */ 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); event RewardsDurationUpdated(uint256 newDuration); event Recovered(address token, uint256 amount); }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_rewardsDistribution","internalType":"address"},{"type":"address","name":"_rewardsToken","internalType":"address"},{"type":"address","name":"_stakingToken","internalType":"address"}]},{"type":"event","name":"OwnerChanged","inputs":[{"type":"address","name":"oldOwner","internalType":"address","indexed":false},{"type":"address","name":"newOwner","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"OwnerNominated","inputs":[{"type":"address","name":"newOwner","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Recovered","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardAdded","inputs":[{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardPaid","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"reward","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"RewardsDurationUpdated","inputs":[{"type":"uint256","name":"newDuration","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Staked","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrawn","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"earned","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"exit","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"getReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getRewardForDuration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastTimeRewardApplicable","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastUpdateTime","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"nominateNewOwner","inputs":[{"type":"address","name":"_owner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"nominatedOwner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"notifyRewardAmount","inputs":[{"type":"uint256","name":"reward","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"periodFinish","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"recoverERC20","inputs":[{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint256","name":"tokenAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardPerToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardPerTokenStored","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardRate","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewards","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"rewardsDistribution","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"rewardsDuration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"rewardsToken","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRewardsDistribution","inputs":[{"type":"address","name":"_rewardsDistribution","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setRewardsDuration","inputs":[{"type":"uint256","name":"_rewardsDuration","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stake","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"stakingToken","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updatePeriodFinish","inputs":[{"type":"uint256","name":"timestamp","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"userRewardPerTokenPaid","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]}]
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101ce5760003560e01c806372f702f311610104578063a694fc3a116100a2578063d1af0c7d11610071578063d1af0c7d146103f9578063df136d6514610419578063e9fad8ee14610422578063ebe2b12b1461042a576101ce565b8063a694fc3a146103c2578063c8f33c91146103d5578063cc1a378f146103de578063cd3daf9d146103f1576101ce565b806380faa57d116100de57806380faa57d146103675780638980f11f1461036f5780638b876347146103825780638da5cb5b146103a2576101ce565b806372f702f31461033657806379ba5097146103565780637b0a47ee1461035e576101ce565b8063386a9525116101715780633fc6df6e1161014b5780633fc6df6e1461028857806353a47bb7146102cd578063556f6e6b146102ed57806370a0823114610300576101ce565b8063386a9525146102645780633c6b16ab1461026d5780633d18b91214610280576101ce565b806318160ddd116101ad57806318160ddd1461022e57806319762143146102365780631c1f78eb146102495780632e1a7d4d14610251576101ce565b80628cc262146101d35780630700037d146101f95780631627540c14610219575b600080fd5b6101e66101e13660046117c0565b610433565b6040519081526020015b60405180910390f35b6101e66102073660046117c0565b600c6020526000908152604090205481565b61022c6102273660046117c0565b6104cd565b005b6101e661054f565b61022c6102443660046117c0565b610556565b6101e66105a5565b61022c61025f366004611823565b6105c3565b6101e660085481565b61022c61027b366004611823565b6107bb565b61022c610ab1565b6002546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f0565b6001546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c6102fb366004611823565b610c1f565b6101e661030e3660046117c0565b73ffffffffffffffffffffffffffffffffffffffff166000908152600e602052604090205490565b6005546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c610ca3565b6101e660075481565b6101e6610dee565b61022c61037d3660046117da565b610dfc565b6101e66103903660046117c0565b600b6020526000908152604090205481565b6000546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b61022c6103d0366004611823565b610f29565b6101e660095481565b61022c6103ec366004611823565b611110565b6101e6611204565b6004546102a89073ffffffffffffffffffffffffffffffffffffffff1681565b6101e6600a5481565b61022c611252565b6101e660065481565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020908152604080832054600b9092528220546104c591906104bf90670de0b6b3a7640000906104b99061048d90610487611204565b90611275565b73ffffffffffffffffffffffffffffffffffffffff88166000908152600e602052604090205490611288565b90611294565b906112a0565b90505b919050565b6104d56112ac565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020015b60405180910390a150565b600d545b90565b61055e6112ac565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60006105be60085460075461128890919063ffffffff16565b905090565b60026003541415610635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064015b60405180910390fd5b600260035533610643611204565b600a5561064e610dee565b60095573ffffffffffffffffffffffffffffffffffffffff8116156106af5761067681610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b60008211610719576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f43616e6e6f742077697468647261772030000000000000000000000000000000604482015260640161062c565b600d546107269083611275565b600d55336000908152600e60205260409020546107439083611275565b336000818152600e602052604090209190915560055461077c9173ffffffffffffffffffffffffffffffffffffffff9091169084611353565b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5906020015b60405180910390a250506001600355565b60025473ffffffffffffffffffffffffffffffffffffffff163314610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f43616c6c6572206973206e6f742052657761726473446973747269627574696f60448201527f6e20636f6e747261637400000000000000000000000000000000000000000000606482015260840161062c565b600061086c611204565b600a55610877610dee565b60095573ffffffffffffffffffffffffffffffffffffffff8116156108d85761089f81610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b60065442106108f7576008546108ef908390611294565b60075561093a565b6006546000906109079042611275565b905060006109206007548361128890919063ffffffff16565b600854909150610934906104b986846112a0565b60075550505b600480546040517f70a08231000000000000000000000000000000000000000000000000000000008152309281019290925260009173ffffffffffffffffffffffffffffffffffffffff909116906370a082319060240160206040518083038186803b1580156109a957600080fd5b505afa1580156109bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e1919061183b565b90506109f86008548261129490919063ffffffff16565b6007541115610a63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f50726f76696465642072657761726420746f6f20686967680000000000000000604482015260640161062c565b426009819055600854610a7691906112a0565b6006556040518381527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d9060200160405180910390a1505050565b60026003541415610b1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161062c565b600260035533610b2c611204565b600a55610b37610dee565b60095573ffffffffffffffffffffffffffffffffffffffff811615610b9857610b5f81610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b336000908152600c60205260409020548015610c1657336000818152600c6020526040812055600454610be49173ffffffffffffffffffffffffffffffffffffffff9091169083611353565b60405181815233907fe2403640ba68fed3a2f88b7557551d1993f84b99bb10ff833f0cf8db0c5e0486906020016107aa565b50506001600355565b610c276112ac565b6000610c31611204565b600a55610c3c610dee565b60095573ffffffffffffffffffffffffffffffffffffffff811615610c9d57610c6481610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b50600655565b60015473ffffffffffffffffffffffffffffffffffffffff163314610d4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527f2063616e20616363657074206f776e6572736869700000000000000000000000606482015260840161062c565b6000546001546040805173ffffffffffffffffffffffffffffffffffffffff93841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b60006105be4260065461142c565b610e046112ac565b60055473ffffffffffffffffffffffffffffffffffffffff83811691161415610eaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f43616e6e6f7420776974686472617720746865207374616b696e6720746f6b6560448201527f6e00000000000000000000000000000000000000000000000000000000000000606482015260840161062c565b600054610ed69073ffffffffffffffffffffffffffffffffffffffff848116911683611353565b6040805173ffffffffffffffffffffffffffffffffffffffff84168152602081018390527f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa28910160405180910390a15050565b60026003541415610f96576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161062c565b600260035533610fa4611204565b600a55610faf610dee565b60095573ffffffffffffffffffffffffffffffffffffffff81161561101057610fd781610433565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832093909355600a54600b909152919020555b6000821161107a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f43616e6e6f74207374616b652030000000000000000000000000000000000000604482015260640161062c565b600d5461108790836112a0565b600d55336000908152600e60205260409020546110a490836112a0565b336000818152600e60205260409020919091556005546110de9173ffffffffffffffffffffffffffffffffffffffff909116903085611442565b60405182815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d906020016107aa565b6111186112ac565b60065442116111cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605860248201527f50726576696f7573207265776172647320706572696f64206d7573742062652060448201527f636f6d706c657465206265666f7265206368616e67696e67207468652064757260648201527f6174696f6e20666f7220746865206e657720706572696f640000000000000000608482015260a40161062c565b60088190556040518181527ffb46ca5a5e06d4540d6387b930a7c978bce0db5f449ec6b3f5d07c6e1d44f2d390602001610544565b6000600d546000141561121a5750600a54610553565b6105be611249600d546104b9670de0b6b3a7640000611243600754611243600954610487610dee565b90611288565b600a54906112a0565b336000908152600e602052604090205461126b906105c3565b611273610ab1565b565b6000611281828461194e565b9392505050565b60006112818284611911565b600061128182846118d8565b600061128182846118c0565b60005473ffffffffffffffffffffffffffffffffffffffff163314611273576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201527f6f726d207468697320616374696f6e0000000000000000000000000000000000606482015260840161062c565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526114279084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526114a6565b505050565b600081831061143b5781611281565b5090919050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526114a09085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016113a5565b50505050565b6000611508826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166115b29092919063ffffffff16565b80519091501561142757808060200190518101906115269190611803565b611427576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161062c565b60606115c184846000856115c9565b949350505050565b60608247101561165b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c0000000000000000000000000000000000000000000000000000606482015260840161062c565b843b6116c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161062c565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516116ec9190611853565b60006040518083038185875af1925050503d8060008114611729576040519150601f19603f3d011682016040523d82523d6000602084013e61172e565b606091505b509150915061173e828286611749565b979650505050505050565b60608315611758575081611281565b8251156117685782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062c919061186f565b803573ffffffffffffffffffffffffffffffffffffffff811681146104c857600080fd5b6000602082840312156117d1578081fd5b6112818261179c565b600080604083850312156117ec578081fd5b6117f58361179c565b946020939093013593505050565b600060208284031215611814578081fd5b81518015158114611281578182fd5b600060208284031215611834578081fd5b5035919050565b60006020828403121561184c578081fd5b5051919050565b60008251611865818460208701611965565b9190910192915050565b600060208252825180602084015261188e816040850160208701611965565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b600082198211156118d3576118d3611991565b500190565b60008261190c577f4e487b710000000000000000000000000000000000000000000000000000000081526012600452602481fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561194957611949611991565b500290565b60008282101561196057611960611991565b500390565b60005b83811015611980578181015183820152602001611968565b838111156114a05750506000910152565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea26469706673582212204741156476b1119a35758ba68769b1a7738761c3a0698f422dff39246b0a32a164736f6c63430008030033