Contract
0x230a59F4d9ADc147480f03B0D3fFfeCd56c3289a
7
Contract Overview
Balance:
0 xDAI
xDAI Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xf1b6844ed66ea8b26e126184356bd33b52ebf9edb5bdfb8040f8bb72849f759d | 0x6020610e | 26615208 | 106 days 15 hrs ago | 0x089775364ea24957da94348cf740375826ed3330 | IN | Create: Vyper_contract | 0 xDAI | 0.001567694065 |
[ Download CSV Export ]
View more zero value Internal Transactions in Advanced View mode
Contract Source Code Verified (Exact Match)
Contract Name:
Vyper_contract
Compiler Version
vyper:0.3.1
Contract Source Code (Vyper language format)
# @version 0.3.1 """ @title Child-Chain Streamer @author Curve.Fi @license MIT @notice Evenly streams one or more reward tokens to a single recipient """ from vyper.interfaces import ERC20 event RewardDistributorUpdated: reward_token: indexed(address) distributor: address event RewardDurationUpdated: reward_token: indexed(address) duration: uint256 struct RewardToken: distributor: address period_finish: uint256 rate: uint256 duration: uint256 received: uint256 paid: uint256 MAX_REWARDS: constant(uint256) = 8 WEEK: constant(uint256) = 7 * 86400 BAL_TOKEN: immutable(address) AUTHORIZER_ADAPTOR: immutable(address) # The reward receiver is actually immutable, but kept in storage due to this contract being used via proxies reward_receiver: public(address) reward_tokens: public(address[MAX_REWARDS]) reward_count: public(uint256) reward_data: public(HashMap[address, RewardToken]) last_update_time: public(uint256) @external def __init__(_bal_token: address, _authorizerAdaptor: address): BAL_TOKEN = _bal_token AUTHORIZER_ADAPTOR = _authorizerAdaptor # prevent initialization of implementation self.reward_receiver = 0x000000000000000000000000000000000000dEaD @internal def _add_reward(_token: address, _distributor: address, _duration: uint256): """ @notice Add a reward token @param _token Address of the reward token @param _distributor Address permitted to call `notify_reward_amount` for this token @param _duration Number of seconds that rewards of this token are streamed over """ assert self.reward_data[_token].distributor == ZERO_ADDRESS, "Reward token already added" idx: uint256 = self.reward_count self.reward_tokens[idx] = _token self.reward_count = idx + 1 self.reward_data[_token].distributor = _distributor self.reward_data[_token].duration = _duration log RewardDistributorUpdated(_token, _distributor) log RewardDurationUpdated(_token, _duration) @external def add_reward(_token: address, _distributor: address, _duration: uint256): """ @notice Add a reward token @param _token Address of the reward token @param _distributor Address permitted to call `notify_reward_amount` for this token @param _duration Number of seconds that rewards of this token are streamed over """ assert msg.sender == AUTHORIZER_ADAPTOR # dev: owner only self._add_reward(_token, _distributor, _duration) @external def remove_reward(_token: address, _recipient: address): """ @notice Remove a reward token @dev Any remaining balance of the reward token is transferred to the owner @param _token Address of the reward token @param _recipient Address to receive the removed tokens """ assert msg.sender == AUTHORIZER_ADAPTOR # dev: only owner assert self.reward_data[_token].distributor != ZERO_ADDRESS, "Reward token not added" self.reward_data[_token] = empty(RewardToken) amount: uint256 = ERC20(_token).balanceOf(self) response: Bytes[32] = raw_call( _token, concat( method_id("transfer(address,uint256)"), convert(_recipient, bytes32), convert(amount, bytes32), ), max_outsize=32, ) if len(response) != 0: assert convert(response, bool) idx: uint256 = self.reward_count - 1 for i in range(MAX_REWARDS): if self.reward_tokens[i] == _token: self.reward_tokens[i] = self.reward_tokens[idx] self.reward_tokens[idx] = ZERO_ADDRESS self.reward_count = idx log RewardDistributorUpdated(_token, ZERO_ADDRESS) log RewardDurationUpdated(_token, 0) return raise # this should never be reached @internal def _update_reward(_token: address, _last_update: uint256): # update data about a reward and distribute any pending tokens to the receiver last_time: uint256 = min(block.timestamp, self.reward_data[_token].period_finish) if last_time > _last_update: amount: uint256 = (last_time - _last_update) * self.reward_data[_token].rate if amount > 0: self.reward_data[_token].paid += amount response: Bytes[32] = raw_call( _token, concat( method_id("transfer(address,uint256)"), convert(self.reward_receiver, bytes32), convert(amount, bytes32), ), max_outsize=32, ) if len(response) != 0: assert convert(response, bool) @external def get_reward(): """ @notice Claim pending rewards for `reward_receiver` """ last_update: uint256 = self.last_update_time for token in self.reward_tokens: if token == ZERO_ADDRESS: break self._update_reward(token, last_update) self.last_update_time = block.timestamp @external def notify_reward_amount(_token: address): """ @notice Notify the contract of a newly received reward @dev Only callable by the distributor if there is an active reward period. The reward tokens must be transferred into the contract prior to calling this function. Rewards are distributed over `reward_duration` seconds. Updating the reward amount while an existing reward period is still active causes the remaining rewards to be evenly distributed over the new period. @param _token Address of the reward token """ last_update: uint256 = self.last_update_time is_updated: bool = False for token in self.reward_tokens: if token == ZERO_ADDRESS: break self._update_reward(token, last_update) if token == _token: received: uint256 = self.reward_data[token].received expected_balance: uint256 = received - self.reward_data[token].paid actual_balance: uint256 = ERC20(token).balanceOf(self) if actual_balance > expected_balance: new_amount: uint256 = actual_balance - expected_balance duration: uint256 = self.reward_data[token].duration if block.timestamp >= self.reward_data[token].period_finish: self.reward_data[token].rate = new_amount / duration else: assert msg.sender == self.reward_data[_token].distributor, "Reward period still active" remaining: uint256 = self.reward_data[token].period_finish - block.timestamp leftover: uint256 = remaining * self.reward_data[token].rate self.reward_data[token].rate = (new_amount + leftover) / duration self.reward_data[token].period_finish = block.timestamp + duration self.reward_data[token].received = received + new_amount is_updated = True assert is_updated, "Invalid token or no new reward" self.last_update_time = block.timestamp @external def set_reward_duration(_token: address, _duration: uint256): """ @notice Modify the duration that rewards are distributed over @dev Only callable when there is not an active reward period @param _token Address of the reward token @param _duration Number of seconds to distribute rewards over """ assert msg.sender == self.reward_data[_token].distributor # dev: only owner assert block.timestamp > self.reward_data[_token].period_finish, "Reward period still active" self.reward_data[_token].duration = _duration log RewardDurationUpdated(_token, _duration) @external def set_reward_distributor(_token: address, _distributor: address): """ @notice Modify the reward distributor @param _token Address of the reward token @param _distributor Reward distributor """ assert msg.sender == self.reward_data[_token].distributor or msg.sender == AUTHORIZER_ADAPTOR self.reward_data[_token].distributor = _distributor log RewardDistributorUpdated(_token, _distributor) # Initializer @external def initialize(reward_receiver: address): """ @notice Contract constructor @param reward_receiver RewardsOnlyGauge address """ assert self.reward_receiver == ZERO_ADDRESS assert reward_receiver != ZERO_ADDRESS self.reward_receiver = reward_receiver # The first reward token will always be BAL, we then have the authorizer adaptor # as the distributor to ensure that governance has the ability to distribute. # The Authorizer adaptor can always update the distributor should Balancer governance wish. self._add_reward(BAL_TOKEN, AUTHORIZER_ADAPTOR, WEEK)
[{"name":"RewardDistributorUpdated","inputs":[{"name":"reward_token","type":"address","indexed":true},{"name":"distributor","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"RewardDurationUpdated","inputs":[{"name":"reward_token","type":"address","indexed":true},{"name":"duration","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_bal_token","type":"address"},{"name":"_authorizerAdaptor","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"add_reward","inputs":[{"name":"_token","type":"address"},{"name":"_distributor","type":"address"},{"name":"_duration","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"remove_reward","inputs":[{"name":"_token","type":"address"},{"name":"_recipient","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"get_reward","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"notify_reward_amount","inputs":[{"name":"_token","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_reward_duration","inputs":[{"name":"_token","type":"address"},{"name":"_duration","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"set_reward_distributor","inputs":[{"name":"_token","type":"address"},{"name":"_distributor","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"initialize","inputs":[{"name":"reward_receiver","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"reward_receiver","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"reward_tokens","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"reward_count","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"reward_data","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"distributor","type":"address"},{"name":"period_finish","type":"uint256"},{"name":"rate","type":"uint256"},{"name":"duration","type":"uint256"},{"name":"received","type":"uint256"},{"name":"paid","type":"uint256"}]}]},{"stateMutability":"view","type":"function","name":"last_update_time","inputs":[],"outputs":[{"name":"","type":"uint256"}]}]
Contract Creation Code
6020610e176080396080518060a01c610e125760e05260206020610e17016080396080518060a01c610e12576101005260e05161012052610100516101405261dead600055610de056600436101561000d57610a8d565b60046000601c3760005134610d925763661ab0b28118610077576004358060a01c610d9257610180526024358060a01c610d92576101a0526020602038036080396080513318610d92576101805160e0526101a0516101005260443561012052610075610a93565b005b63393e582b81186103ac576004358060a01c610d925760e0526024358060a01c610d9257610100526020602038036080396080513318610d92576000600a60e05160a052608052604060802054141561013f576016610120527f52657761726420746f6b656e206e6f74206164646564000000000000000000006101405261012050610120518061014001818260206001820306601f82010390500336823750506308c379a060e0526020610100526101205160206001820306601f820103905060440160fcfd5b600a60e05160a0526080526040608020600081556000600182015560006002820155600060038201556000600482015560006005820155506370a082316101405230610160526020610140602461015c60e0515afa6101a3573d600060003e3d6000fd5b601f3d1115610d9257610140516101205260006004610180527fa9059cbb000000000000000000000000000000000000000000000000000000006101a0526101806004806020846101c00101826020850160045afa505080518201915050610100516020826101c0010152602081019050610120516020826101c0010152602081019050806101c0526101c0505060206102606101c0516101e0600060e0515af1610253573d600060003e3d6000fd5b61024060203d8082116102665781610268565b805b905090508152805160200180610140828460045afa90505050600061014051146102a757610160516101405181816020036008021c9050905015610d92575b6009546001808210610d925780820390509050610180526101a060006008818352015b60e05160016101a0516008811015610d9257026001015418610393576001610180516008811015610d9257026001015460016101a0516008811015610d9257026001015560006001610180516008811015610d925702600101556101805160095560e0517f1df95772db25c427e0df149fe4cd5b7c2e970e096ee7305ff86f6e1167281d7b60006101c05260206101c0a260e0517f2c59073844bbfca50d5cce6497d479fe434747687af5de022514e5a0c8ba479c60006101c05260206101c0a25050506103aa565b81516001018083528114156102ca57505060006000fd5b005b631afe22a6811861041257600b546102a0526102e060006008818352015b6102e051600101546102c0526102c0516103e35761040a565b6102c05160e0526102a051610100526103fa610bea565b81516001018083528114156103ca575b505042600b55005b63a4f6af7081186107ac576004358060a01c610d92576102a052600b546102c05260006102e05261032060006008818352015b6103205160010154610300526103005161045e57610725565b6103005160e0526102c05161010052610475610bea565b6102a0516103005118610715576004600a6103005160a0526080526040608020015461034052610340516005600a6103005160a05260805260406080200154808210610d925780820390509050610360526370a082316103a052306103c05260206103a060246103bc610300515afa6104f3573d600060003e3d6000fd5b601f3d1115610d92576103a0516103805261036051610380511115610715576103805161036051808210610d9257808203905090506103a0526003600a6103005160a052608052604060802001546103c0526001600a6103005160a0526080526040608020015442101561068c57600a6102a05160a05260805260406080205433146105f057601a6103e0527f52657761726420706572696f64207374696c6c20616374697665000000000000610400526103e0506103e0518061040001818260206001820306601f82010390500336823750506308c379a06103a05260206103c0526103e05160206001820306601f82010390506044016103bcfd5b6001600a6103005160a0526080526040608020015442808210610d9257808203905090506103e0526103e0516002600a6103005160a05260805260406080200154808202821582848304141715610d925790509050610400526103a051610400518181830110610d9257808201905090506103c051808015610d92578204905090506002600a6103005160a052608052604060802001556106b7565b6103a0516103c051808015610d92578204905090506002600a6103005160a052608052604060802001555b426103c0518181830110610d9257808201905090506001600a6103005160a05260805260406080200155610340516103a0518181830110610d9257808201905090506004600a6103005160a0526080526040608020015560016102e0525b8151600101808352811415610445575b50506102e0516107a657601e610300527f496e76616c696420746f6b656e206f72206e6f206e65772072657761726400006103205261030050610300518061032001818260206001820306601f82010390500336823750506308c379a06102c05260206102e0526103005160206001820306601f82010390506044016102dcfd5b42600b55005b63d88449ee81186108b4576004358060a01c610d925760e052600a60e05160a0526080526040608020543318610d92576001600a60e05160a05260805260406080200154421161086a57601a610100527f52657761726420706572696f64207374696c6c206163746976650000000000006101205261010050610100518061012001818260206001820306601f82010390500336823750506308c379a060c052602060e0526101005160206001820306601f820103905060440160dcfd5b6024356003600a60e05160a0526080526040608020015560e0517f2c59073844bbfca50d5cce6497d479fe434747687af5de022514e5a0c8ba479c602435610100526020610100a2005b63058a3a248118610957576004358060a01c610d925760e0526024358060a01c610d925761010052600a60e05160a05260805260406080205433186108fa576001610909565b60206020380360803960805133145b15610d925761010051600a60e05160a05260805260406080205560e0517f1df95772db25c427e0df149fe4cd5b7c2e970e096ee7305ff86f6e1167281d7b61010051610120526020610120a2005b63c4d66de881186109bb576004358060a01c610d925761018052600054610d925760006101805114610d92576101805160005560206040380360803960805160e0526020602038036080396080516101005262093a80610120526109b9610a93565b005b63b618ba6281186109d25760005460e052602060e0f35b6354c49fe981186109f95760016004356008811015610d9257026001015460e052602060e0f35b63963c94b98118610a105760095460e052602060e0f35b6348e9c65e8118610a74576004358060a01c610d925760e052600a60e05160a052608052604060802080546101005260018101546101205260028101546101405260038101546101605260048101546101805260058101546101a0525060c0610100f35b63629d46c28118610a8b57600b5460e052602060e0f35b505b60006000fd5b600a60e05160a05260805260406080205415610b2057601a610140527f52657761726420746f6b656e20616c72656164792061646465640000000000006101605261014050610140518061016001818260206001820306601f82010390500336823750506308c379a0610100526020610120526101405160206001820306601f820103905060440161011cfd5b6009546101405260e0516001610140516008811015610d925702600101556101405160018181830110610d92578082019050905060095561010051600a60e05160a052608052604060802055610120516003600a60e05160a0526080526040608020015560e0517f1df95772db25c427e0df149fe4cd5b7c2e970e096ee7305ff86f6e1167281d7b61010051610160526020610160a260e0517f2c59073844bbfca50d5cce6497d479fe434747687af5de022514e5a0c8ba479c61012051610160526020610160a2565b426001600a60e05160a05260805260406080200154808211610c0c5781610c0e565b805b905090506101205261010051610120511115610d90576101205161010051808210610d9257808203905090506002600a60e05160a05260805260406080200154808202821582848304141715610d925790509050610140526000610140511115610d90576005600a60e05160a0526080526040608020018054610140518181830110610d925780820190509050815550600060046101a0527fa9059cbb000000000000000000000000000000000000000000000000000000006101c0526101a06004806020846101e00101826020850160045afa5050805182019150506000546020826101e0010152602081019050610140516020826101e0010152602081019050806101e0526101e0505060206102806101e051610200600060e0515af1610d3c573d600060003e3d6000fd5b61026060203d808211610d4f5781610d51565b805b905090508152805160200180610160828460045afa9050505060006101605114610d9057610180516101605181816020036008021c9050905015610d92575b565b600080fd5b610049610de00361004961016039610049610de003610120518161016001526101405181610180015280604001610160f35b600080fd0000000000000000000000007ef541e2a22058048904fe5744f9c7e4c57af7170000000000000000000000005addcca35b7a0d07c74063c48700c8590e87864e
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007ef541e2a22058048904fe5744f9c7e4c57af7170000000000000000000000005addcca35b7a0d07c74063c48700c8590e87864e
-----Decoded View---------------
Arg [0] : _bal_token (address): 0x7ef541e2a22058048904fe5744f9c7e4c57af717
Arg [1] : _authorizerAdaptor (address): 0x5addcca35b7a0d07c74063c48700c8590e87864e
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007ef541e2a22058048904fe5744f9c7e4c57af717
Arg [1] : 0000000000000000000000005addcca35b7a0d07c74063c48700c8590e87864e
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.