Contract 0x104f1459a2ffea528121759b238bb609034c2f01 6

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x622aa0db1702555c743139f1c8a78c8bcf3f626a8401bc52d5ddfc8b9b450434Deposit281469432022-10-03 10:26:4328 mins ago0x19e2c558ced66d661daeacc571a0b44c1e62c408 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002226
0x1eb1d2464c5e23f00d42eb96323013a0e56e0c148286f4dfc628cf12dff23a9cDeposit281468842022-10-03 10:26:0528 mins ago0x76483d453f35a946de3a42cb814649480fe97e3e IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002756
0x6ea38b65acdeb895059f3a572449f62a08f76dccf56a29743c629f2a93f83420Deposit281464052022-10-03 10:21:3533 mins ago0xc3ec49da24f841407acc34f31b653151e03301bf IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002238
0xd94f3f09960783a9a898c7e9432f9b76b2ec5e88d321c4c3bf0912c6af5b60a1Deposit281445252022-10-03 10:03:0151 mins ago0x799816d058d116bd18aa6e941bf1860158a43b0f IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002136
0xe1214541ac221f7c5ac5e7de645ea703023cf225da2373725ac6dd4b33ec8743Deposit281427092022-10-03 9:46:381 hr 8 mins ago0x6cc3715b07bf0d5247bc574ae752645d1f34b925 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002078
0x63198f22528b8890bba5488a5a50cf65cd05c47e9e3e59e93cb8abe111794c0fDeposit281419162022-10-03 9:39:491 hr 15 mins ago0x670d325e99c57ea55cb505b11624dc933eda82a5 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002084
0x1768bcad4bf29cba436d2a62aee7f48b45f45e6b9ce8579627673ef9c426bb21Deposit281404232022-10-03 9:27:301 hr 27 mins ago0xbb8574ad63a1159aa774e79d73d18804ddea2f9c IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002065
0x183f1695a8e9d6a6eabb17f4a5d1417aad67952f62213a8900e2ae45a0759339Deposit281402062022-10-03 9:25:541 hr 29 mins ago0xff853110731b3b764596d695d7ac52b6c7895ccb IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002106
0xe45da9ba1c5ce90b9e25cc6766a8d2e6fadefab9831ea3d4700cb8eb47ac8aa3Deposit281399142022-10-03 9:23:521 hr 31 mins ago0x81e1e25d47afe72cb360ac72848ad2a5ef9dd70e IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002636
0xf4d8255f717405ec6267100090ce8ac40dcd077b588c1d049179ff1116736247Deposit281370832022-10-03 9:05:301 hr 49 mins ago0xa48f6184a1a746d5034edb5ea0101e94c64931f0 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00001259
0x0b794fb944e454409d01e22336b6f97adaef61527a0c67fc558b8e4b99802d0bDeposit281351292022-10-03 8:52:522 hrs 2 mins ago0x1a853ccb4bd7020a46b5ffcf3e2ddb75765387b3 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00001951
0xc64ab4cd8249ea8d983dbcd570a30b3c554cae1edd4e2f6b758cabeb74abfe96Deposit281343402022-10-03 8:47:242 hrs 7 mins ago0x5c2632cedb167609c7f12e9bbfbc5665cfd66d40 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00001825
0x531998215b3155a5944cb7609280185096ee1383d57a36607d0568948a6edef2Deposit281339622022-10-03 8:45:072 hrs 9 mins ago0xac27a1fc083f8fe958ca36fa9a0426ac8c3a1b38 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002114
0x2408f1a80669a8c59fcd8e6763ec5bd0f45da17072efde6ddf5d5d9c44e67c92Deposit281339512022-10-03 8:45:022 hrs 9 mins ago0x050aef55a207806354adc7f07d167a68a508061c IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002114
0x2d2b87b55a4a321b70eb84cc5ff99f9aea85967f4a633452d96014a8a47f965dDeposit281339482022-10-03 8:45:012 hrs 9 mins ago0x7aadc19b1dde0fe812798a1205b4f55adde1e76b IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002114
0x2f4d61e691fb24ea8b7f2a5a1bdf7695f49d2e786e04d693cfab1596f5a1ecf4Deposit281339442022-10-03 8:45:002 hrs 9 mins ago0xd2f034933c2748d7683930f5fdab2531be69d06c IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002114
0x0129f1f811bb1f7aa2c4e713a3a3daac454e33c609a1816acdecf9c42db0d080Withdraw281330412022-10-03 8:38:362 hrs 16 mins ago0x9d386325330ff9565821232435c67b253776fed9 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.0000191
0x51b7c9d8eb267960b80e622ffd93d254665bcec0bfa035df72999cc05dfb28efDeposit281326562022-10-03 8:36:002 hrs 18 mins ago0x9d386325330ff9565821232435c67b253776fed9 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002138
0x1be53463da4183480ad23d9602b3c5322c43d8f63262cb5335d184ce9acd18ebWithdraw281320542022-10-03 8:31:482 hrs 23 mins ago0xb429abcfd6da4273a5379f8a534a343458926cda IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002101
0x09efa4643665d643296a7a320f9f94dcc2ad1e883faefb8d87e265fcd82e6efaDeposit281302522022-10-03 8:18:532 hrs 36 mins ago0x97f16b00d436fcd49d5911e68002f1cd4d5e47c5 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.0000207
0x0cec9dfc29a1a7dd0942bde9668d4e0f6809dead80efb9df3fdcae3e0ac05637Deposit281288532022-10-03 8:10:032 hrs 44 mins ago0xe18ed82de38ee79a475624b1a5f2783d4d7c62ef IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00002074
0x0463cc1f2e6332ac8ffebab4149ae0250bb548848baaa6251119c01a945abc1fDeposit281276682022-10-03 8:02:542 hrs 52 mins ago0x1682db78a752c660b31bc185ef0c4e221bb93f36 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00001784
0x22a0b1b578b30a275b8a6ff7233d8f00f7978fa83ee3d1087a9344a3034bddf8Deposit281276052022-10-03 8:02:302 hrs 52 mins ago0x37ecd58d161daf7980aaeb669c016614d9588366 IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00001951
0xdbb795a94b1a30c22807aa78cf73c4ce0c974dd4d328165bb1d5329c0565fbbeWithdraw281270332022-10-03 7:58:402 hrs 56 mins ago0x4e4bfd82429cd8c3f2e3979273d872f8c1ee4c9c IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.0000245
0xf1e0b434bc871481342b0b45003959be1922b3de3ecf93f5ff3091b9dc903ce5Withdraw281197692022-10-03 7:12:023 hrs 42 mins ago0x7b589c14a323c201bdcd251a23e001438c2520ba IN  0x104f1459a2ffea528121759b238bb609034c2f010 ETH0.00001917
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x622aa0db1702555c743139f1c8a78c8bcf3f626a8401bc52d5ddfc8b9b450434281469432022-10-03 10:26:4328 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x64541216bafffeec8ea535bb71fbc927831d05950 ETH
0x622aa0db1702555c743139f1c8a78c8bcf3f626a8401bc52d5ddfc8b9b450434281469432022-10-03 10:26:4328 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0x622aa0db1702555c743139f1c8a78c8bcf3f626a8401bc52d5ddfc8b9b450434281469432022-10-03 10:26:4328 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x1eb1d2464c5e23f00d42eb96323013a0e56e0c148286f4dfc628cf12dff23a9c281468842022-10-03 10:26:0528 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x64541216bafffeec8ea535bb71fbc927831d05950 ETH
0x1eb1d2464c5e23f00d42eb96323013a0e56e0c148286f4dfc628cf12dff23a9c281468842022-10-03 10:26:0528 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0x1eb1d2464c5e23f00d42eb96323013a0e56e0c148286f4dfc628cf12dff23a9c281468842022-10-03 10:26:0528 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x4b1137789ff06406a72bace67cd15cf6786844cc0 ETH
0x1eb1d2464c5e23f00d42eb96323013a0e56e0c148286f4dfc628cf12dff23a9c281468842022-10-03 10:26:0528 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x6ea38b65acdeb895059f3a572449f62a08f76dccf56a29743c629f2a93f83420281464052022-10-03 10:21:3533 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x64541216bafffeec8ea535bb71fbc927831d05950 ETH
0x6ea38b65acdeb895059f3a572449f62a08f76dccf56a29743c629f2a93f83420281464052022-10-03 10:21:3533 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0x6ea38b65acdeb895059f3a572449f62a08f76dccf56a29743c629f2a93f83420281464052022-10-03 10:21:3533 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0xd94f3f09960783a9a898c7e9432f9b76b2ec5e88d321c4c3bf0912c6af5b60a1281445252022-10-03 10:03:0151 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x64541216bafffeec8ea535bb71fbc927831d05950 ETH
0xd94f3f09960783a9a898c7e9432f9b76b2ec5e88d321c4c3bf0912c6af5b60a1281445252022-10-03 10:03:0151 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0xd94f3f09960783a9a898c7e9432f9b76b2ec5e88d321c4c3bf0912c6af5b60a1281445252022-10-03 10:03:0151 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0xe87ec49cdc21014df4fc3f96692deb7ffab3d874 0x104f1459a2ffea528121759b238bb609034c2f010 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0xe87ec49cdc21014df4fc3f96692deb7ffab3d874 0x104f1459a2ffea528121759b238bb609034c2f010 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x64541216bafffeec8ea535bb71fbc927831d05950 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0x104f1459a2ffea528121759b238bb609034c2f010x040d1edc9569d4bab2d15287dc5a4f10f56a56b80 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0xe87ec49cdc21014df4fc3f96692deb7ffab3d874 0x104f1459a2ffea528121759b238bb609034c2f010 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0xe87ec49cdc21014df4fc3f96692deb7ffab3d874 0x104f1459a2ffea528121759b238bb609034c2f010 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0x104f1459a2ffea528121759b238bb609034c2f01 0x41b953164995c11c81da73d212ed8af25741b7ac0 ETH
0x86657b884a639307b7ce29d99e09a9075a37f42f076ff4c814e6485788aff54a281442392022-10-03 10:00:1254 mins ago 0xe87ec49cdc21014df4fc3f96692deb7ffab3d874 0x104f1459a2ffea528121759b238bb609034c2f010 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.