Contract 0xfaad21203a7856889cb6eb644ab6864e7253107a 1

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xdbde0be84a27953c15c07b372a333c6a405c286ac3ee42c0052822f966107e25Withdraw276343232022-09-30 16:09:1715 hrs 22 mins ago0x7d873fbfe8e16f5f55740a52a356c2f52c613cdf IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00003564
0x2e6808e14ac9cfaae604070b0f611e52d6bdb85e524658af212c3bb866c21c72Withdraw276306052022-09-30 15:44:0015 hrs 48 mins ago0x93c631f40f1eeef0edf4809b9b31b600f622e47f IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00003713
0x9168c2e10145b261c6d4d2a0549e708c24beae3c026accadc1cc7e25f2b0a4b2Withdraw275640972022-09-30 8:44:4622 hrs 47 mins ago0x8fc4faa9dd274dc801ca629234e83183031634ec IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002222
0xad5cebecaea2de93d1255f2143150c71d6e30c212634586594c8d1d5a398464cWithdraw274050582022-09-29 11:38:231 day 19 hrs ago0xe2dcfb3621fd1970b4289f1f8251c6d1efb9d0af IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00001973
0xa37a6443669becf25583d01af36d8613488b2e800d89d87d2cd0bdeffc385702Withdraw273153492022-09-29 1:57:522 days 5 hrs ago0xb192d3b9cf7db5a9b215d693e966f11894b59696 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002215
0xd828f6cc5d475bb5001f145a2024dcd57ab04882a1275faef444fcc2f37e814bWithdraw272775792022-09-28 19:24:482 days 12 hrs ago0x8a4a50b13fd2cb36feb96c408cb98b4c9f2b8f25 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00004103
0x60ae3b7cf1e287042c924006bc54b8ab76a1a18e25ba33cdca8583ecd6ab1432Claim_rewards272760052022-09-28 19:10:152 days 12 hrs ago0x8a4a50b13fd2cb36feb96c408cb98b4c9f2b8f25 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00003929
0x6d14ef4e558a6845e8602da71373524c3c683ef8b92560849d3e1e6a328e6af5Withdraw271887392022-09-28 10:34:102 days 20 hrs ago0xbdbbb9935cb25d14fdc9494aa4f6abf5a5e6aef5 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002339
0x58e87aebfdd3b0b98818a43fa4f88f0790d97b1830f5aa981ee1a931ead24584Withdraw271587342022-09-28 7:58:452 days 23 hrs ago0x939d65c9b31b7d3de6bc93a473829a9268706dfd IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002576
0x8c6fea8c139d7a55fb07950e77ed45902ec29f752ad4978c6f99de43a5b27dcfWithdraw270230912022-09-27 16:07:433 days 15 hrs ago0xc9ca2ba9a27de1db589d8c33ab8edfa2111b31fb IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00004023
0xc1689be55c1eee9ed1281177f337a3e3697db7ca351426afdfd5e8e02f194afeWithdraw269288522022-09-27 5:33:484 days 1 hr ago0xdf06a761d286c0ae835173236e1f12f1379e4977 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002247
0xf0e17977f1da740572585317a33c4491a092b302916357743c7d4e1fd7e9f1bbDeposit269117252022-09-27 3:12:294 days 4 hrs ago0x7b7b2500f881c1fa03f083906f3d02e318032297 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.0000259
0xc9d6355519ec0673c2caa71e60ea010d2ecfe5398ef18c32d00b278193083d3fDeposit268083842022-09-26 13:00:344 days 18 hrs ago0xadaf1b41f751c91a88347fade6e6fbca1a73276f IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00001945
0x440229e224f0127f9091f7e0f0dd1c812d00c7fb924d3094a4bcabdbee5c8af3Withdraw266678442022-09-25 22:08:415 days 9 hrs ago0x2cef35ddad95cd702ac8bc9ef423abae9155ee1c IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002311
0x79a784616adb1dcbd93cf43028fe6530e1241595e5912d3637cbcb8ed26e1df1Deposit266549792022-09-25 20:14:065 days 11 hrs ago0xc59b1c8017b295233a291cb0b31cd72f624c5d36 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00001998
0xc959c309fde4a8a8e0d384b5e7505a91be20e1a4f6fccc897feae124fff37c04Deposit266547302022-09-25 20:11:455 days 11 hrs ago0xc317eb33a06b7d218b3b9cf21b727cb5f557b20c IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00001998
0x3c68fc1e5d52c7e6b20b0c30acf577f31891ae9ad6b613d364ac9969e16611f7Deposit266542732022-09-25 20:07:225 days 11 hrs ago0xd45dd445b2960595e22c26491ddd483aeec17b1f IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002246
0x882f0d8b1a3d461bf689a760099111a0cfe332245af1cafc839d3596d8915c7cDeposit266442282022-09-25 18:41:225 days 12 hrs ago0xd3b5373f12efb7d862b9ec1f02ed8a1c1a5fce9a IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.0000237
0xb0340f635018b163a8ffbf41911a567fadb0be411d6b81fdc57cec2f942410f9Deposit266441392022-09-25 18:40:265 days 12 hrs ago0xc9085262988133b7244eea515e62954c4edce12a IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002377
0xc985d1626efe5347dc7d866b64791a4c1f322baeedc7887d43206b9aab1b2925Deposit266439502022-09-25 18:38:355 days 12 hrs ago0x06a636e2bd7748165ff5d62906c80f192c4f83e2 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002377
0xec9cfe3e6f1712c47491ad8b46df391484e36e49dda164a10d7ae8086da6e0b6Deposit266436282022-09-25 18:35:395 days 12 hrs ago0x80a71ffc85570c54f542d77682aaee54038d027d IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002387
0xc3d13fd3de29dfbcdf76c1a0ee1ceb1df03fb2199c822206fbaf730bb277f75fDeposit266434902022-09-25 18:34:125 days 12 hrs ago0x4b26aa1539e5ffcb1443e24091cd3a5a3a8656c7 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002387
0x4073fc33cf64e29f80a6ca47d9ffde362c7b6a324ce0079ddef5c7e2d753b359Deposit266432682022-09-25 18:31:495 days 13 hrs ago0x4a78183de1e6558567423fd6b38f2d7a92b6c1ab IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002387
0xae0bb0640b090ec5c6903bcfdb81769dad562cdbb01dbee0efbf45216c45c44cDeposit266431372022-09-25 18:30:355 days 13 hrs ago0xa1c2e3726db298d14d55d24d877d70837b4a4c53 IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002385
0x86401a9276d197d08004867c7833b2b0ad815c096503eb9b7c45ae99d97e296fDeposit266429932022-09-25 18:29:155 days 13 hrs ago0x6c47a9a3ada73c92db42137ca701ed76d191061e IN  0xfaad21203a7856889cb6eb644ab6864e7253107a0 ETH0.00002385
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xdbde0be84a27953c15c07b372a333c6a405c286ac3ee42c0052822f966107e25276343232022-09-30 16:09:1715 hrs 22 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0xcc65a812ce382ab909a11e434dbf75b34f1cc59d0 ETH
0xdbde0be84a27953c15c07b372a333c6a405c286ac3ee42c0052822f966107e25276343232022-09-30 16:09:1715 hrs 22 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0xdbde0be84a27953c15c07b372a333c6a405c286ac3ee42c0052822f966107e25276343232022-09-30 16:09:1715 hrs 22 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x2e6808e14ac9cfaae604070b0f611e52d6bdb85e524658af212c3bb866c21c72276306052022-09-30 15:44:0015 hrs 48 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0xcc65a812ce382ab909a11e434dbf75b34f1cc59d0 ETH
0x2e6808e14ac9cfaae604070b0f611e52d6bdb85e524658af212c3bb866c21c72276306052022-09-30 15:44:0015 hrs 48 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0x2e6808e14ac9cfaae604070b0f611e52d6bdb85e524658af212c3bb866c21c72276306052022-09-30 15:44:0015 hrs 48 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0xd5cd8328d93bf4bef9824fd288f32c8f0da1c5510 ETH
0x2e6808e14ac9cfaae604070b0f611e52d6bdb85e524658af212c3bb866c21c72276306052022-09-30 15:44:0015 hrs 48 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x9168c2e10145b261c6d4d2a0549e708c24beae3c026accadc1cc7e25f2b0a4b2275640972022-09-30 8:44:4622 hrs 47 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0xcc65a812ce382ab909a11e434dbf75b34f1cc59d0 ETH
0x9168c2e10145b261c6d4d2a0549e708c24beae3c026accadc1cc7e25f2b0a4b2275640972022-09-30 8:44:4622 hrs 47 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0x9168c2e10145b261c6d4d2a0549e708c24beae3c026accadc1cc7e25f2b0a4b2275640972022-09-30 8:44:4622 hrs 47 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0xd5cd8328d93bf4bef9824fd288f32c8f0da1c5510 ETH
0x9168c2e10145b261c6d4d2a0549e708c24beae3c026accadc1cc7e25f2b0a4b2275640972022-09-30 8:44:4622 hrs 47 mins ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0xad5cebecaea2de93d1255f2143150c71d6e30c212634586594c8d1d5a398464c274050582022-09-29 11:38:231 day 19 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0xcc65a812ce382ab909a11e434dbf75b34f1cc59d0 ETH
0xad5cebecaea2de93d1255f2143150c71d6e30c212634586594c8d1d5a398464c274050582022-09-29 11:38:231 day 19 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0xad5cebecaea2de93d1255f2143150c71d6e30c212634586594c8d1d5a398464c274050582022-09-29 11:38:231 day 19 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0xd5cd8328d93bf4bef9824fd288f32c8f0da1c5510 ETH
0xad5cebecaea2de93d1255f2143150c71d6e30c212634586594c8d1d5a398464c274050582022-09-29 11:38:231 day 19 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0xa37a6443669becf25583d01af36d8613488b2e800d89d87d2cd0bdeffc385702273153492022-09-29 1:57:522 days 5 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0xcc65a812ce382ab909a11e434dbf75b34f1cc59d0 ETH
0xa37a6443669becf25583d01af36d8613488b2e800d89d87d2cd0bdeffc385702273153492022-09-29 1:57:522 days 5 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0xa37a6443669becf25583d01af36d8613488b2e800d89d87d2cd0bdeffc385702273153492022-09-29 1:57:522 days 5 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0xd5cd8328d93bf4bef9824fd288f32c8f0da1c5510 ETH
0xa37a6443669becf25583d01af36d8613488b2e800d89d87d2cd0bdeffc385702273153492022-09-29 1:57:522 days 5 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0xd828f6cc5d475bb5001f145a2024dcd57ab04882a1275faef444fcc2f37e814b272775792022-09-28 19:24:482 days 12 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0xcc65a812ce382ab909a11e434dbf75b34f1cc59d0 ETH
0xd828f6cc5d475bb5001f145a2024dcd57ab04882a1275faef444fcc2f37e814b272775792022-09-28 19:24:482 days 12 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0xd828f6cc5d475bb5001f145a2024dcd57ab04882a1275faef444fcc2f37e814b272775792022-09-28 19:24:482 days 12 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x60ae3b7cf1e287042c924006bc54b8ab76a1a18e25ba33cdca8583ecd6ab1432272760052022-09-28 19:10:152 days 12 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x00000000000000000000000000000000000000040 ETH
0x60ae3b7cf1e287042c924006bc54b8ab76a1a18e25ba33cdca8583ecd6ab1432272760052022-09-28 19:10:152 days 12 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0x60ae3b7cf1e287042c924006bc54b8ab76a1a18e25ba33cdca8583ecd6ab1432272760052022-09-28 19:10:152 days 12 hrs ago 0xfaad21203a7856889cb6eb644ab6864e7253107a0x00000000000000000000000000000000000000040 ETH
[ Download CSV Export 
Loading

Minimal Proxy Contract for 0x41b953164995c11c81da73d212ed8af25741b7ac

Contract Name:
Vyper_contract

Compiler Version
vyper:0.3.1

Optimization Enabled:
N/A

Other Settings:
, MIT license
Decompile ByteCode

Contract Source Code (Vyper language format)

# @version 0.3.1
"""
@title Rewards-Only Gauge
@author Curve Finance
@license MIT
@notice Distribution of third-party rewards without CRV
"""

from vyper.interfaces import ERC20

implements: ERC20

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

interface Streamer:
    def reward_data(_token: address) -> RewardToken: view
    def last_update_time() -> uint256: view

interface ERC20Extended:
    def symbol() -> String[26]: view

interface ERC1271:
    def isValidSignature(_hash: bytes32, _signature: Bytes[65]) -> bytes32: view

event Deposit:
    provider: indexed(address)
    value: uint256

event Withdraw:
    provider: indexed(address)
    value: uint256

event Transfer:
    _from: indexed(address)
    _to: indexed(address)
    _value: uint256

event Approval:
    _owner: indexed(address)
    _spender: indexed(address)
    _value: uint256

struct Reward:
    token: address
    distributor: address
    period_finish: uint256
    rate: uint256
    last_update: uint256
    integral: uint256

MAX_REWARDS: constant(uint256) = 8
CLAIM_FREQUENCY: constant(uint256) = 3600

# keccak256("isValidSignature(bytes32,bytes)")[:4] << 224
ERC1271_MAGIC_VAL: constant(bytes32) = 0x1626ba7e00000000000000000000000000000000000000000000000000000000
VERSION: constant(String[8]) = "v1.0.0"

EIP712_TYPEHASH: constant(bytes32) = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
PERMIT_TYPEHASH: constant(bytes32) = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")

BAL_TOKEN: immutable(address)
BAL_VAULT: immutable(address)
AUTHORIZER_ADAPTOR: immutable(address)

lp_token: public(address)

balanceOf: public(HashMap[address, uint256])
totalSupply: public(uint256)
_allowance: HashMap[address, HashMap[address, uint256]]

name: public(String[64])
symbol: public(String[40])

# ERC2612
DOMAIN_SEPARATOR: public(bytes32)
nonces: public(HashMap[address, uint256])

# For tracking external rewards
_reward_data: uint256
reward_tokens: public(address[MAX_REWARDS])
reward_balances: public(HashMap[address, uint256])
# claimant -> default reward receiver
rewards_receiver: public(HashMap[address, address])

claim_sig: public(Bytes[4])

# reward token -> integral
reward_integral: public(HashMap[address, uint256])

# reward token -> claiming address -> integral
reward_integral_for: public(HashMap[address, HashMap[address, uint256]])

# user -> [uint128 claimable amount][uint128 claimed amount]
claim_data: HashMap[address, HashMap[address, uint256]]


@external
def __init__(_bal_token: address, _vault: address, _authorizerAdaptor: address):
    """
    @notice Contract constructor
    @param _vault Balancer Vault contract address
    """

    BAL_TOKEN = _bal_token
    BAL_VAULT = _vault
    AUTHORIZER_ADAPTOR = _authorizerAdaptor

    # prevent initialization of implementation
    self.lp_token = 0x000000000000000000000000000000000000dEaD

@view
@external
def decimals() -> uint256:
    """
    @notice Get the number of decimals for this token
    @dev Implemented as a view method to reduce gas costs
    @return uint256 decimal places
    """
    return 18

@view
@external
def version() -> String[8]:
    """
    @notice Get the version of this gauge contract
    """
    return VERSION

@view
@internal
def _get_allowance(owner: address, spender: address) -> uint256:
    """
     @dev Override to grant the Vault infinite allowance, causing for Gauge Tokens to not require approval.
     This is sound as the Vault already provides authorization mechanisms when initiating token transfers, which this
     contract inherits.
    """
    if (spender == BAL_VAULT):
        return MAX_UINT256
    return self._allowance[owner][spender]

@internal
def _checkpoint_rewards(_user: address, _total_supply: uint256, _claim: bool, _receiver: address):
    """
    @notice Claim pending rewards and checkpoint rewards for a user
    """
    # claim from reward contract

    reward_data: uint256 = self._reward_data
    if _total_supply != 0 and reward_data != 0 and block.timestamp > shift(reward_data, -160) + CLAIM_FREQUENCY:
        reward_contract: address = convert(reward_data % 2**160, address)
        raw_call(reward_contract, self.claim_sig)  # dev: bad claim sig
        self._reward_data = convert(reward_contract, uint256) + shift(block.timestamp, 160)

    receiver: address = _receiver
    if _claim and receiver == ZERO_ADDRESS:
        # if receiver is not explicitly declared, check for default receiver
        receiver = self.rewards_receiver[_user]
        if receiver == ZERO_ADDRESS:
            # direct claims to user if no default receiver is set
            receiver = _user

    # calculate new user reward integral and transfer any owed rewards
    user_balance: uint256 = self.balanceOf[_user]
    for i in range(MAX_REWARDS):
        token: address = self.reward_tokens[i]
        if token == ZERO_ADDRESS:
            break
        dI: uint256 = 0
        if _total_supply != 0:
            token_balance: uint256 = ERC20(token).balanceOf(self)
            dI = 10**18 * (token_balance - self.reward_balances[token]) / _total_supply
            self.reward_balances[token] = token_balance
            if _user == ZERO_ADDRESS:
                if dI != 0:
                    self.reward_integral[token] += dI
                continue

        integral: uint256 = self.reward_integral[token] + dI
        if dI != 0:
            self.reward_integral[token] = integral

        integral_for: uint256 = self.reward_integral_for[token][_user]
        new_claimable: uint256 = 0
        if integral_for < integral:
            self.reward_integral_for[token][_user] = integral
            new_claimable = user_balance * (integral - integral_for) / 10**18

        claim_data: uint256 = self.claim_data[_user][token]
        total_claimable: uint256 = shift(claim_data, -128) + new_claimable
        if total_claimable > 0:
            total_claimed: uint256 = claim_data % 2 ** 128
            if _claim:
                response: Bytes[32] = raw_call(
                    token,
                    concat(
                        method_id("transfer(address,uint256)"),
                        convert(receiver, bytes32),
                        convert(total_claimable, bytes32),
                    ),
                    max_outsize=32,
                )
                if len(response) != 0:
                    assert convert(response, bool)
                self.reward_balances[token] -= total_claimable
                # update amount claimed (lower order bytes)
                self.claim_data[_user][token] = total_claimed + total_claimable
            elif new_claimable > 0:
                # update total_claimable (higher order bytes)
                self.claim_data[_user][token] = total_claimed + shift(total_claimable, 128)


@view
@external
def reward_contract() -> address:
    """
    @notice Address of the reward contract providing non-CRV incentives for this gauge
    @dev Returns `ZERO_ADDRESS` if there is no reward contract active
    """
    return convert(self._reward_data % 2**160, address)


@view
@external
def last_claim() -> uint256:
    """
    @notice Epoch timestamp of the last call to claim from `reward_contract`
    @dev Rewards are claimed at most once per hour in order to reduce gas costs
    """
    return shift(self._reward_data, -160)


@view
@external
def claimed_reward(_addr: address, _token: address) -> uint256:
    """
    @notice Get the number of already-claimed reward tokens for a user
    @param _addr Account to get reward amount for
    @param _token Token to get reward amount for
    @return uint256 Total amount of `_token` already claimed by `_addr`
    """
    return self.claim_data[_addr][_token] % 2**128


@view
@external
def claimable_reward(_addr: address, _token: address) -> uint256:
    """
    @notice Get the number of claimable reward tokens for a user
    @dev This call does not consider pending claimable amount in `reward_contract`.
         Off-chain callers should instead use `claimable_rewards_write` as a
         view method.
    @param _addr Account to get reward amount for
    @param _token Token to get reward amount for
    @return uint256 Claimable reward token amount
    """
    return shift(self.claim_data[_addr][_token], -128)

@view
@external
def reward_data(_token: address) -> Reward:
    reward_contract: address = convert(self._reward_data % 2**160, address)
    reward_token: RewardToken = Streamer(reward_contract).reward_data(_token)
    last_update_time: uint256 = Streamer(reward_contract).last_update_time()
    return Reward({
        token: _token,
        distributor: reward_token.distributor,
        period_finish: reward_token.period_finish,
        rate: reward_token.rate,
        last_update: last_update_time,
        integral: self.reward_integral[_token]
    })


@external
@nonreentrant('lock')
def claimable_reward_write(_addr: address, _token: address) -> uint256:
    """
    @notice Get the number of claimable reward tokens for a user
    @dev This function should be manually changed to "view" in the ABI
         Calling it via a transaction will claim available reward tokens
    @param _addr Account to get reward amount for
    @param _token Token to get reward amount for
    @return uint256 Claimable reward token amount
    """
    if self.reward_tokens[0] != ZERO_ADDRESS:
        self._checkpoint_rewards(_addr, self.totalSupply, False, ZERO_ADDRESS)
    return shift(self.claim_data[_addr][_token], -128)


@external
def set_rewards_receiver(_receiver: address):
    """
    @notice Set the default reward receiver for the caller.
    @dev When set to ZERO_ADDRESS, rewards are sent to the caller
    @param _receiver Receiver address for any rewards claimed via `claim_rewards`
    """
    self.rewards_receiver[msg.sender] = _receiver


@external
@nonreentrant('lock')
def claim_rewards(_addr: address = msg.sender, _receiver: address = ZERO_ADDRESS):
    """
    @notice Claim available reward tokens for `_addr`
    @param _addr Address to claim for
    @param _receiver Address to transfer rewards to - if set to
                     ZERO_ADDRESS, uses the default reward receiver
                     for the caller
    """
    if _receiver != ZERO_ADDRESS:
        assert _addr == msg.sender  # dev: cannot redirect when claiming for another user
    self._checkpoint_rewards(_addr, self.totalSupply, True, _receiver)


@external
@nonreentrant('lock')
def deposit(_value: uint256, _addr: address = msg.sender, _claim_rewards: bool = False):
    """
    @notice Deposit `_value` LP tokens
    @dev Depositting also claims pending reward tokens
    @param _value Number of tokens to deposit
    @param _addr Address to deposit for
    """
    if _value != 0:
        reward_contract: address = convert(self._reward_data % 2**160, address)
        total_supply: uint256 = self.totalSupply

        self._checkpoint_rewards(_addr, total_supply, _claim_rewards, ZERO_ADDRESS)

        total_supply += _value
        new_balance: uint256 = self.balanceOf[_addr] + _value
        self.balanceOf[_addr] = new_balance
        self.totalSupply = total_supply

        ERC20(self.lp_token).transferFrom(msg.sender, self, _value)

    log Deposit(_addr, _value)
    log Transfer(ZERO_ADDRESS, _addr, _value)


@external
@nonreentrant('lock')
def withdraw(_value: uint256, _claim_rewards: bool = False):
    """
    @notice Withdraw `_value` LP tokens
    @dev Withdrawing also claims pending reward tokens
    @param _value Number of tokens to withdraw
    """
    if _value != 0:
        reward_contract: address = convert(self._reward_data % 2**160, address)
        total_supply: uint256 = self.totalSupply

        self._checkpoint_rewards(msg.sender, total_supply, _claim_rewards, ZERO_ADDRESS)

        total_supply -= _value
        new_balance: uint256 = self.balanceOf[msg.sender] - _value
        self.balanceOf[msg.sender] = new_balance
        self.totalSupply = total_supply

        ERC20(self.lp_token).transfer(msg.sender, _value)

    log Withdraw(msg.sender, _value)
    log Transfer(msg.sender, ZERO_ADDRESS, _value)


@internal
def _transfer(_from: address, _to: address, _value: uint256):
    reward_contract: address = convert(self._reward_data % 2**160, address)

    if _value != 0:
        total_supply: uint256 = self.totalSupply
        self._checkpoint_rewards(_from, total_supply, False, ZERO_ADDRESS)
        new_balance: uint256 = self.balanceOf[_from] - _value
        self.balanceOf[_from] = new_balance

        self._checkpoint_rewards(_to, total_supply, False, ZERO_ADDRESS)
        new_balance = self.balanceOf[_to] + _value
        self.balanceOf[_to] = new_balance

    log Transfer(_from, _to, _value)


@external
@nonreentrant('lock')
def transfer(_to : address, _value : uint256) -> bool:
    """
    @notice Transfer token for a specified address
    @dev Transferring claims pending reward tokens for the sender and receiver
    @param _to The address to transfer to.
    @param _value The amount to be transferred.
    """
    self._transfer(msg.sender, _to, _value)

    return True


@external
@nonreentrant('lock')
def transferFrom(_from : address, _to : address, _value : uint256) -> bool:
    """
    @notice Transfer tokens from one address to another.
    @dev Transferring claims pending reward tokens for the sender and receiver
    @param _from address The address which you want to send tokens from
    @param _to address The address which you want to transfer to
    @param _value uint256 the amount of tokens to be transferred
    """
    _allowance: uint256 = self._get_allowance(_from, msg.sender)
    if _allowance != MAX_UINT256:
        self._allowance[_from][msg.sender] = _allowance - _value

    self._transfer(_from, _to, _value)

    return True

@view
@external
def allowance(owner: address, spender: address) -> uint256:
    """
     @notice Get `spender`'s current allowance from `owner` 
    """
    return self._get_allowance(owner, spender)

@external
def approve(_spender : address, _value : uint256) -> bool:
    """
    @notice Approve the passed address to transfer the specified amount of
            tokens on behalf of msg.sender
    @dev Beware that changing an allowance via this method brings the risk
         that someone may use both the old and new allowance by unfortunate
         transaction ordering. This may be mitigated with the use of
         {incraseAllowance} and {decreaseAllowance}.
         https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
    @param _spender The address which will transfer the funds
    @param _value The amount of tokens that may be transferred
    @return bool success
    """
    self._allowance[msg.sender][_spender] = _value
    log Approval(msg.sender, _spender, _value)

    return True

@external
def permit(
    _owner: address,
    _spender: address,
    _value: uint256,
    _deadline: uint256,
    _v: uint8,
    _r: bytes32,
    _s: bytes32
) -> bool:
    """
    @notice Approves spender by owner's signature to expend owner's tokens.
        See https://eips.ethereum.org/EIPS/eip-2612.
    @dev Inspired by https://github.com/yearn/yearn-vaults/blob/main/contracts/Vault.vy#L753-L793
    @dev Supports smart contract wallets which implement ERC1271
        https://eips.ethereum.org/EIPS/eip-1271
    @param _owner The address which is a source of funds and has signed the Permit.
    @param _spender The address which is allowed to spend the funds.
    @param _value The amount of tokens to be spent.
    @param _deadline The timestamp after which the Permit is no longer valid.
    @param _v The bytes[64] of the valid secp256k1 signature of permit by owner
    @param _r The bytes[0:32] of the valid secp256k1 signature of permit by owner
    @param _s The bytes[32:64] of the valid secp256k1 signature of permit by owner
    @return True, if transaction completes successfully
    """
    assert _owner != ZERO_ADDRESS
    assert block.timestamp <= _deadline

    nonce: uint256 = self.nonces[_owner]
    digest: bytes32 = keccak256(
        concat(
            b"\x19\x01",
            self.DOMAIN_SEPARATOR,
            keccak256(_abi_encode(PERMIT_TYPEHASH, _owner, _spender, _value, nonce, _deadline))
        )
    )

    if _owner.is_contract:
        sig: Bytes[65] = concat(_abi_encode(_r, _s), slice(convert(_v, bytes32), 31, 1))
        # reentrancy not a concern since this is a staticcall
        assert ERC1271(_owner).isValidSignature(digest, sig) == ERC1271_MAGIC_VAL
    else:
        assert ecrecover(digest, convert(_v, uint256), convert(_r, uint256), convert(_s, uint256)) == _owner

    self._allowance[_owner][_spender] = _value
    self.nonces[_owner] = nonce + 1

    log Approval(_owner, _spender, _value)
    return True

@external
def increaseAllowance(_spender: address, _added_value: uint256) -> bool:
    """
    @notice Increase the allowance granted to `_spender` by the caller
    @dev This is alternative to {approve} that can be used as a mitigation for
         the potential race condition
    @param _spender The address which will transfer the funds
    @param _added_value The amount of to increase the allowance
    @return bool success
    """
    allowance: uint256 = self._get_allowance(msg.sender, _spender) + _added_value
    self._allowance[msg.sender][_spender] = allowance

    log Approval(msg.sender, _spender, allowance)

    return True


@external
def decreaseAllowance(_spender: address, _subtracted_value: uint256) -> bool:
    """
    @notice Decrease the allowance granted to `_spender` by the caller
    @dev This is alternative to {approve} that can be used as a mitigation for
         the potential race condition
    @param _spender The address which will transfer the funds
    @param _subtracted_value The amount of to decrease the allowance
    @return bool success
    """
    allowance: uint256 = self._get_allowance(msg.sender, _spender) - _subtracted_value
    self._allowance[msg.sender][_spender] = allowance

    log Approval(msg.sender, _spender, allowance)

    return True

@internal
def _set_rewards(_reward_contract: address, _claim_sig: bytes32, _reward_tokens: address[MAX_REWARDS]):
    """
    @notice Set the active reward contract
    @dev A reward contract cannot be set while this contract has no deposits
    @param _reward_contract Reward contract address. Set to ZERO_ADDRESS to
                            disable staking.
    @param _claim_sig Four byte selectors for staking, withdrawing and claiming,
                 left padded with zero bytes. If the reward contract can
                 be claimed from but does not require staking, the staking
                 and withdraw selectors should be set to 0x00
    @param _reward_tokens List of claimable reward tokens. New reward tokens
                          may be added but they cannot be removed. When calling
                          this function to unset or modify a reward contract,
                          this array must begin with the already-set reward
                          token addresses.
    """
    lp_token: address = self.lp_token
    current_reward_contract: address = convert(self._reward_data % 2**160, address)
    total_supply: uint256 = self.totalSupply
    self._checkpoint_rewards(ZERO_ADDRESS, total_supply, False, ZERO_ADDRESS)

    if _reward_contract != ZERO_ADDRESS:
        assert _reward_tokens[0] != ZERO_ADDRESS  # dev: no reward token
        assert _reward_contract.is_contract  # dev: not a contract

    self._reward_data = convert(_reward_contract, uint256)
    self.claim_sig = slice(_claim_sig, 28, 4)
    for i in range(MAX_REWARDS):
        current_token: address = self.reward_tokens[i]
        new_token: address = _reward_tokens[i]
        if current_token != ZERO_ADDRESS:
            assert current_token == new_token  # dev: cannot modify existing reward token
        elif new_token != ZERO_ADDRESS:
            self.reward_tokens[i] = new_token
        else:
            break

    if _reward_contract != ZERO_ADDRESS:
        # do an initial checkpoint to verify that claims are working
        self._checkpoint_rewards(ZERO_ADDRESS, total_supply, False, ZERO_ADDRESS)

@external
@nonreentrant('lock')
def set_rewards(_reward_contract: address, _claim_sig: bytes32, _reward_tokens: address[MAX_REWARDS]):
    """
    @notice Set the active reward contract
    @dev A reward contract cannot be set while this contract has no deposits
    @param _reward_contract Reward contract address. Set to ZERO_ADDRESS to
                            disable staking.
    @param _claim_sig Four byte selectors for staking, withdrawing and claiming,
                 left padded with zero bytes. If the reward contract can
                 be claimed from but does not require staking, the staking
                 and withdraw selectors should be set to 0x00
    @param _reward_tokens List of claimable reward tokens. New reward tokens
                          may be added but they cannot be removed. When calling
                          this function to unset or modify a reward contract,
                          this array must begin with the already-set reward
                          token addresses.
    """
    assert msg.sender == AUTHORIZER_ADAPTOR  # dev: only owner
    self._set_rewards(_reward_contract, _claim_sig, _reward_tokens)

# Initializer

@external
def initialize(_lp_token: address, _reward_contract: address, _claim_sig: bytes32):
    """
    @notice Contract constructor
    @param _lp_token Liquidity Pool contract address
    """
    assert self.lp_token == ZERO_ADDRESS
    assert _lp_token != ZERO_ADDRESS

    self.lp_token = _lp_token

    symbol: String[32] = ERC20Extended(_lp_token).symbol()
    name: String[64] = concat("Balancer ", symbol, " RewardGauge Deposit")

    self.name = name
    self.symbol = concat(symbol, "-gauge")

    self.DOMAIN_SEPARATOR = keccak256(
        _abi_encode(EIP712_TYPEHASH, keccak256(name), keccak256(VERSION), chain.id, self)
    )

    # Initialise connection to ChildChainStreamer contract
    reward_tokens: address[MAX_REWARDS] = empty(address[MAX_REWARDS])
    reward_tokens[0] = BAL_TOKEN
    self._set_rewards(_reward_contract, _claim_sig, reward_tokens)

Contract ABI

[{"name":"Deposit","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Withdraw","inputs":[{"name":"provider","type":"address","indexed":true},{"name":"value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Transfer","inputs":[{"name":"_from","type":"address","indexed":true},{"name":"_to","type":"address","indexed":true},{"name":"_value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"Approval","inputs":[{"name":"_owner","type":"address","indexed":true},{"name":"_spender","type":"address","indexed":true},{"name":"_value","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_bal_token","type":"address"},{"name":"_vault","type":"address"},{"name":"_authorizerAdaptor","type":"address"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"decimals","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"reward_contract","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"last_claim","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"claimed_reward","inputs":[{"name":"_addr","type":"address"},{"name":"_token","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"claimable_reward","inputs":[{"name":"_addr","type":"address"},{"name":"_token","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"reward_data","inputs":[{"name":"_token","type":"address"}],"outputs":[{"name":"","type":"tuple","components":[{"name":"token","type":"address"},{"name":"distributor","type":"address"},{"name":"period_finish","type":"uint256"},{"name":"rate","type":"uint256"},{"name":"last_update","type":"uint256"},{"name":"integral","type":"uint256"}]}]},{"stateMutability":"nonpayable","type":"function","name":"claimable_reward_write","inputs":[{"name":"_addr","type":"address"},{"name":"_token","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"set_rewards_receiver","inputs":[{"name":"_receiver","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim_rewards","inputs":[],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim_rewards","inputs":[{"name":"_addr","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"claim_rewards","inputs":[{"name":"_addr","type":"address"},{"name":"_receiver","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"_value","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"_value","type":"uint256"},{"name":"_addr","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"deposit","inputs":[{"name":"_value","type":"uint256"},{"name":"_addr","type":"address"},{"name":"_claim_rewards","type":"bool"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"_value","type":"uint256"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"withdraw","inputs":[{"name":"_value","type":"uint256"},{"name":"_claim_rewards","type":"bool"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"transfer","inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"transferFrom","inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"view","type":"function","name":"allowance","inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"nonpayable","type":"function","name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"permit","inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_deadline","type":"uint256"},{"name":"_v","type":"uint8"},{"name":"_r","type":"bytes32"},{"name":"_s","type":"bytes32"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"increaseAllowance","inputs":[{"name":"_spender","type":"address"},{"name":"_added_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"decreaseAllowance","inputs":[{"name":"_spender","type":"address"},{"name":"_subtracted_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}]},{"stateMutability":"nonpayable","type":"function","name":"set_rewards","inputs":[{"name":"_reward_contract","type":"address"},{"name":"_claim_sig","type":"bytes32"},{"name":"_reward_tokens","type":"address[8]"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"initialize","inputs":[{"name":"_lp_token","type":"address"},{"name":"_reward_contract","type":"address"},{"name":"_claim_sig","type":"bytes32"}],"outputs":[]},{"stateMutability":"view","type":"function","name":"lp_token","inputs":[],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"balanceOf","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"totalSupply","inputs":[],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"name","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"symbol","inputs":[],"outputs":[{"name":"","type":"string"}]},{"stateMutability":"view","type":"function","name":"DOMAIN_SEPARATOR","inputs":[],"outputs":[{"name":"","type":"bytes32"}]},{"stateMutability":"view","type":"function","name":"nonces","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"reward_tokens","inputs":[{"name":"arg0","type":"uint256"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"reward_balances","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"rewards_receiver","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"address"}]},{"stateMutability":"view","type":"function","name":"claim_sig","inputs":[],"outputs":[{"name":"","type":"bytes"}]},{"stateMutability":"view","type":"function","name":"reward_integral","inputs":[{"name":"arg0","type":"address"}],"outputs":[{"name":"","type":"uint256"}]},{"stateMutability":"view","type":"function","name":"reward_integral_for","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}]}]

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.