POL Price: $0.219194 (+1.10%)
Gas: 31 GWei
 

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Notify_reward_am...279409862022-05-05 5:23:311046 days ago1651728211IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.005308350
Notify_reward_am...276701392022-04-28 8:27:551052 days ago1651134475IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0033756550
Notify_reward_am...273932442022-04-21 7:31:001059 days ago1650526260IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.005308350
Notify_reward_am...271206582022-04-14 8:56:491066 days ago1649926609IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.005308350
Notify_reward_am...268515502022-04-07 12:19:291073 days ago1649333969IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0033756550
Notify_reward_am...265731542022-03-31 9:51:421080 days ago1648720302IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.005308350
Notify_reward_am...263083502022-03-24 14:00:091087 days ago1648130409IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.01395378206.682911
Notify_reward_am...260328292022-03-17 8:10:401094 days ago1647504640IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0212332200.00000001
Notify_reward_am...257996802022-03-10 9:51:181101 days ago1646905878IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0212332200.00000001
Notify_reward_am...255292102022-03-03 10:45:281108 days ago1646304328IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0135026200.00000001
Notify_reward_am...252812292022-02-24 4:35:031116 days ago1645677303IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.04783044450.52508632
Notify_reward_am...250427162022-02-17 9:04:271122 days ago1645088667IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0067513100
Notify_reward_am...247678502022-02-10 7:58:301129 days ago1644479910IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0067513100
Notify_reward_am...244913952022-02-03 6:44:391136 days ago1643870679IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0106166100
Notify_reward_am...242177062022-01-27 7:43:571143 days ago1643269437IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0089066100
Notify_reward_am...239498742022-01-20 14:45:151150 days ago1642689915IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0067513100
Notify_reward_am...236672192022-01-13 10:03:201157 days ago1642068200IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0337565500
Notify_reward_am...233982372022-01-06 9:26:071164 days ago1641461167IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0337565500
Notify_reward_am...231345182021-12-30 8:21:181171 days ago1640852478IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0033756550
Notify_reward_am...228589572021-12-23 7:08:191178 days ago1640243299IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.005308350
Notify_reward_am...225835532021-12-16 7:32:051185 days ago1639639925IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.004453350
Notify_reward_am...223102942021-12-09 8:20:241192 days ago1639038024IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0033756550
Notify_reward_am...220409852021-12-02 7:06:391199 days ago1638428799IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0033756550
Notify_reward_am...217721832021-11-25 5:13:451207 days ago1637817225IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.0033756550
Notify_reward_am...214974332021-11-18 1:19:111214 days ago1637198351IN
Curve.fi: ATriCrypto Root Chain Gauge
0 POL0.005308350
View all transactions

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x488E6ef9...114DA8F62
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Vyper_contract

Compiler Version
vyper:0.2.12

Optimization Enabled:
N/A

Other Settings:
default evmVersion, MIT license

Contract Source Code (Vyper language format)

# @version 0.2.12
"""
@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

struct RewardToken:
    distributor: address
    period_finish: uint256
    rate: uint256
    duration: uint256
    received: uint256
    paid: uint256


owner: public(address)
future_owner: public(address)

reward_receiver: public(address)
reward_tokens: public(address[8])
reward_count: public(uint256)
reward_data: public(HashMap[address, RewardToken])
last_update_time: public(uint256)


@external
def __init__(_owner: address):
    self.owner = _owner


@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 == self.owner  # dev: owner only
    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


@external
def remove_reward(_token: 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
    """
    assert msg.sender == self.owner  # 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(msg.sender, 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(8):
        if self.reward_tokens[i] == _token:
            self.reward_tokens[i] = self.reward_tokens[idx]
            self.reward_tokens[idx] = ZERO_ADDRESS
            self.reward_count = idx
            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 set_receiver(_receiver: address):
    """
    @notice Set the reward receiver
    @dev When the receiver is a smart contract, it must be capable of recognizing
         rewards that are directly pushed to it (without a call to `get_reward`)
    @param _receiver Address of the reward receiver
    """
    assert msg.sender == self.owner  # dev: only owner
    self.reward_receiver = _receiver


@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.owner  # dev: only owner
    assert block.timestamp > self.reward_data[_token].period_finish, "Reward period still active"
    self.reward_data[_token].duration = _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.owner  # dev: only owner
    self.reward_data[_token].distributor = _distributor


@external
def commit_transfer_ownership(_owner: address):
    """
    @notice Initiate ownership tansfer of the contract
    @param _owner Address to have ownership transferred to
    """
    assert msg.sender == self.owner  # dev: only owner

    self.future_owner = _owner


@external
def accept_transfer_ownership():
    """
    @notice Accept a pending ownership transfer
    """
    owner: address = self.future_owner
    assert msg.sender == owner  # dev: only new owner

    self.owner = owner

Contract Security Audit

Contract ABI

API
[{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_owner","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"add_reward","inputs":[{"name":"_token","type":"address"},{"name":"_distributor","type":"address"},{"name":"_duration","type":"uint256"}],"outputs":[],"gas":147850},{"stateMutability":"nonpayable","type":"function","name":"remove_reward","inputs":[{"name":"_token","type":"address"}],"outputs":[],"gas":898282},{"stateMutability":"nonpayable","type":"function","name":"set_receiver","inputs":[{"name":"_receiver","type":"address"}],"outputs":[],"gas":37605},{"stateMutability":"nonpayable","type":"function","name":"get_reward","inputs":[],"outputs":[],"gas":496490},{"stateMutability":"nonpayable","type":"function","name":"notify_reward_amount","inputs":[{"name":"_token","type":"address"}],"outputs":[],"gas":1502780},{"stateMutability":"nonpayable","type":"function","name":"set_reward_duration","inputs":[{"name":"_token","type":"address"},{"name":"_duration","type":"uint256"}],"outputs":[],"gas":40303},{"stateMutability":"nonpayable","type":"function","name":"set_reward_distributor","inputs":[{"name":"_token","type":"address"},{"name":"_distributor","type":"address"}],"outputs":[],"gas":38012},{"stateMutability":"nonpayable","type":"function","name":"commit_transfer_ownership","inputs":[{"name":"_owner","type":"address"}],"outputs":[],"gas":37755},{"stateMutability":"nonpayable","type":"function","name":"accept_transfer_ownership","inputs":[],"outputs":[],"gas":37700},{"stateMutability":"view","type":"function","name":"owner","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":2658},{"stateMutability":"view","type":"function","name":"future_owner","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":2688},{"stateMutability":"view","type":"function","name":"reward_receiver","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":2718},{"stateMutability":"view","type":"function","name":"reward_tokens","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}],"gas":2857},{"stateMutability":"view","type":"function","name":"reward_count","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2778},{"stateMutability":"view","type":"function","name":"reward_data","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"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"}],"gas":14685},{"stateMutability":"view","type":"function","name":"last_update_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2838}]

Deployed Bytecode

0x600436101561000d57610c08565b600035601c52600051341561002157600080fd5b63661ab0b28114156101435760043560a01c1561003d57600080fd5b60243560a01c1561004d57600080fd5b600054331461005b57600080fd5b600560043560e05260c052604060c02060c052602060c020541515156100c0576308c379a061014052602061016052601a610180527f52657761726420746f6b656e20616c72656164792061646465640000000000006101a05261018050606461015cfd5b6004546101405260043561014051600881106100db57600080fd5b600360c052602060c02001556101405160018181830110156100fc57600080fd5b80820190509050600455602435600560043560e05260c052604060c02060c052602060c020556044356003600560043560e05260c052604060c02060c052602060c0200155005b635de59dbc81141561045e5760043560a01c1561015f57600080fd5b600054331461016d57600080fd5b6000600560043560e05260c052604060c02060c052602060c02054141515156101d5576308c379a0610140526020610160526016610180527f52657761726420746f6b656e206e6f74206164646564000000000000000000006101a05261018050606461015cfd5b600560043560e05260c052604060c02060c052602060c0206000815560006001820155600060028201556000600382015560006004820155600060058201555060206101e060246370a0823161016052306101805261017c6004355afa61023b57600080fd5b601f3d1161024857600080fd5b6000506101e05161014052600060046101c0527fa9059cbb000000000000000000000000000000000000000000000000000000006101e0526101c060048060208461022001018260208501600060045af15050805182019150503360208261022001015260208101905061014051602082610220010152602081019050806102205261022090508051602001806102c08284600060045af16102e957600080fd5b505060206103806102c0516102e060006004355af161030757600080fd5b60203d80821115610318578061031a565b815b90509050610360526103608051602001806101608284600060045af161033f57600080fd5b505060006101605118156103915761016080602001516000825180602090131561036857600080fd5b809190121561037657600080fd5b806020036101000a8204905090509050151561039157600080fd5b6004546001808210156103a357600080fd5b808203905090506101c0526101e060006008818352015b6004356101e051600881106103ce57600080fd5b600360c052602060c02001541415610446576101c051600881106103f157600080fd5b600360c052602060c02001546101e0516008811061040e57600080fd5b600360c052602060c020015560006101c0516008811061042d57600080fd5b600360c052602060c02001556101c05160045560006000f35b81516001018083528114156103ba575b505060006000fd5b63d1dd6f568114156104905760043560a01c1561047a57600080fd5b600054331461048857600080fd5b600435600255005b631afe22a6811415610527576006546101405261018060006008818352015b61018051600360c052602060c0200154610160526101605115156104d25761051f565b610140516101605161018051610160516101a052610140516101c0526101c0516101a05160065801610c0e565b6101805261016052610140526000505b81516001018083528114156104af575b505042600655005b63a4f6af708114156109265760043560a01c1561054357600080fd5b600654610140526000610160526101a060006008818352015b6101a051600360c052602060c02001546101805261018051151561057f576108cf565b6101405161016051610180516101a051610180516101c052610140516101e0526101e0516101c05160065801610c0e565b6101a0526101805261016052610140526000506004356101805114156108bf57600460056101805160e05260c052604060c02060c052602060c02001546101c0526101c051600560056101805160e05260c052604060c02060c052602060c02001548082101561061f57600080fd5b808203905090506101e05260206102a060246370a0823161022052306102405261023c610180515afa61065157600080fd5b601f3d1161065e57600080fd5b6000506102a051610200526101e0516102005111156108bf57610200516101e0518082101561068c57600080fd5b8082039050905061022052600360056101805160e05260c052604060c02060c052602060c020015461024052600160056101805160e05260c052604060c02060c052602060c02001544210151561071857610220516102405180806106f057600080fd5b820490509050600260056101805160e05260c052604060c02060c052602060c0200155610845565b600560043560e05260c052604060c02060c052602060c020543314151561077e576308c379a061026052602061028052601a6102a0527f52657761726420706572696f64207374696c6c206163746976650000000000006102c0526102a050606461027cfd5b600160056101805160e05260c052604060c02060c052602060c020015442808210156107a957600080fd5b808203905090506102605261026051600260056101805160e05260c052604060c02060c052602060c020015480820282158284830414176107e957600080fd5b8090509050905061028052610220516102805181818301101561080b57600080fd5b8082019050905061024051808061082157600080fd5b820490509050600260056101805160e05260c052604060c02060c052602060c02001555b426102405181818301101561085957600080fd5b80820190509050600160056101805160e05260c052604060c02060c052602060c02001556101c0516102205181818301101561089457600080fd5b80820190509050600460056101805160e05260c052604060c02060c052602060c02001556001610160525b815160010180835281141561055c575b5050610160511515610920576308c379a06101805260206101a052601e6101c0527f496e76616c696420746f6b656e206f72206e6f206e65772072657761726400006101e0526101c050606461019cfd5b42600655005b63d88449ee8114156109da5760043560a01c1561094257600080fd5b600054331461095057600080fd5b6001600560043560e05260c052604060c02060c052602060c0200154421115156109b9576308c379a061014052602061016052601a610180527f52657761726420706572696f64207374696c6c206163746976650000000000006101a05261018050606461015cfd5b6024356003600560043560e05260c052604060c02060c052602060c0200155005b63058a3a24811415610a325760043560a01c156109f657600080fd5b60243560a01c15610a0657600080fd5b6000543314610a1457600080fd5b602435600560043560e05260c052604060c02060c052602060c02055005b636b441a40811415610a645760043560a01c15610a4e57600080fd5b6000543314610a5c57600080fd5b600435600155005b63e5ea47b8811415610a8f5760015461014052610140513314610a8657600080fd5b61014051600055005b638da5cb5b811415610aa75760005460005260206000f35b631ec0cdc1811415610abf5760015460005260206000f35b63b618ba62811415610ad75760025460005260206000f35b6354c49fe9811415610b085760043560088110610af357600080fd5b600360c052602060c020015460005260206000f35b63963c94b9811415610b205760045460005260206000f35b6348e9c65e811415610bee5760043560a01c15610b3c57600080fd5b600560043560e05260c052604060c0206101408080808460c052602060c0205481525050602081019050808060018560c052602060c020015481525050602081019050808060028560c052602060c020015481525050602081019050808060038560c052602060c020015481525050602081019050808060048560c052602060c020015481525050602081019050808060058560c052602060c02001548152505060c09050905060c05260c051610140f35b63629d46c2811415610c065760065460005260206000f35b505b60006000fd5b61018052610140526101605242600160056101405160e05260c052604060c02060c052602060c020015480821115610c465780610c48565b815b905090506101a052610160516101a0511115610e3e576101a0516101605180821015610c7357600080fd5b80820390509050600260056101405160e05260c052604060c02060c052602060c02001548082028215828483041417610cab57600080fd5b809050905090506101c05260006101c0511115610e3e57600560056101405160e05260c052604060c02060c052602060c0200180546101c051818183011015610cf357600080fd5b8082019050905081555060006004610240527fa9059cbb00000000000000000000000000000000000000000000000000000000610260526102406004806020846102a001018260208501600060045af15050805182019150506002546020826102a00101526020810190506101c0516020826102a0010152602081019050806102a0526102a090508051602001806103408284600060045af1610d9557600080fd5b50506020610400610340516103606000610140515af1610db457600080fd5b60203d80821115610dc55780610dc7565b815b905090506103e0526103e08051602001806101e08284600060045af1610dec57600080fd5b505060006101e0511815610e3e576101e0806020015160008251806020901315610e1557600080fd5b8091901215610e2357600080fd5b806020036101000a82049050905090501515610e3e57600080fd5b6101805156

Block Transaction Gas Used Reward
view all blocks produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.