ETH Price: $3,381.74 (+1.02%)

Contract

0x5B0655F938A72052c46d2e94D206ccB6FF625A3A
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Mint214286092024-12-18 9:45:475 days ago1734515147IN
Ribbon Finance: Minter
0 ETH0.002554539.95861858
Mint214159352024-12-16 15:19:597 days ago1734362399IN
Ribbon Finance: Minter
0 ETH0.0060631824.42251108
Mint213001662024-11-30 11:22:2323 days ago1732965743IN
Ribbon Finance: Minter
0 ETH0.001747176.81120191
Mint212925452024-11-29 9:45:5924 days ago1732873559IN
Ribbon Finance: Minter
0 ETH0.001861897.5
Mint212644782024-11-25 11:28:5928 days ago1732534139IN
Ribbon Finance: Minter
0 ETH0.0061520616.0998683
Mint212275872024-11-20 7:53:5933 days ago1732089239IN
Ribbon Finance: Minter
0 ETH0.001728576.73870614
Mint212218202024-11-19 12:36:4734 days ago1732019807IN
Ribbon Finance: Minter
0 ETH0.0103136311.09439494
Mint211957322024-11-15 21:19:3538 days ago1731705575IN
Ribbon Finance: Minter
0 ETH0.0119598126.29703378
Mint210900852024-11-01 3:24:1153 days ago1730431451IN
Ribbon Finance: Minter
0 ETH0.001699046.40295977
Mint210370072024-10-24 17:39:1160 days ago1729791551IN
Ribbon Finance: Minter
0 ETH0.0071598814.36101563
Mint210108862024-10-21 2:12:1164 days ago1729476731IN
Ribbon Finance: Minter
0 ETH0.001754196.83856216
Mint207548212024-09-15 8:28:4799 days ago1726388927IN
Ribbon Finance: Minter
0 ETH0.000556681.86450461
Mint207548052024-09-15 8:25:3599 days ago1726388735IN
Ribbon Finance: Minter
0 ETH0.000568981.80248289
Mint207301262024-09-11 21:42:35103 days ago1726090955IN
Ribbon Finance: Minter
0 ETH0.000626361.81994787
Mint207301122024-09-11 21:39:47103 days ago1726090787IN
Ribbon Finance: Minter
0 ETH0.00074071.97553933
Mint207301032024-09-11 21:37:59103 days ago1726090679IN
Ribbon Finance: Minter
0 ETH0.000568212.05472252
Mint206595842024-09-02 1:25:35113 days ago1725240335IN
Ribbon Finance: Minter
0 ETH0.000147090.57344213
Mint206556502024-09-01 12:14:35113 days ago1725192875IN
Ribbon Finance: Minter
0 ETH0.000186150.71024381
Mint206556462024-09-01 12:13:47113 days ago1725192827IN
Ribbon Finance: Minter
0 ETH0.000185040.66274679
Mint206068582024-08-25 16:40:35120 days ago1724604035IN
Ribbon Finance: Minter
0 ETH0.000207430.80864977
Mint205991772024-08-24 14:52:59121 days ago1724511179IN
Ribbon Finance: Minter
0 ETH0.000319951.24732359
Mint205966412024-08-24 6:22:35121 days ago1724480555IN
Ribbon Finance: Minter
0 ETH0.000221530.92531428
Mint205914022024-08-23 12:49:11122 days ago1724417351IN
Ribbon Finance: Minter
0 ETH0.00039361.53442374
Mint205883362024-08-23 2:30:35123 days ago1724380235IN
Ribbon Finance: Minter
0 ETH0.000290751.13349437
Mint205878772024-08-23 0:57:47123 days ago1724374667IN
Ribbon Finance: Minter
0 ETH0.000328151.12005201
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xcD7dB896...60C2C54ED
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.3.1

Optimization Enabled:
N/A

Other Settings:
default evmVersion, MIT license

Contract Source Code (Vyper language format)

# @version 0.3.1
"""
@title Token Minter
@author Curve Finance
@license MIT
"""

interface LiquidityGauge:
    # Presumably, other gauges will provide the same interfaces
    def integrate_fraction(addr: address) -> uint256: view
    def user_checkpoint(addr: address) -> bool: nonpayable

interface ERC20:
    def transfer(to: address, amount: uint256) -> bool: nonpayable
    def balanceOf(account: address) -> uint256: nonpayable

interface GaugeController:
    def gauge_types(addr: address) -> int128: view

event Minted:
    recipient: indexed(address)
    gauge: address
    minted: uint256

event UpdateMiningParameters:
    time: uint256
    rate: uint256

event CommitNextEmission:
    rate: uint256

event CommitEmergencyReturn:
    admin: address

event ApplyEmergencyReturn:
    admin: address

event CommitOwnership:
    admin: address

event ApplyOwnership:
    admin: address

# General constants
WEEK: constant(uint256) = 86400 * 7

# 250K RBN / WEEK
INITIAL_RATE: constant(uint256) = 250_000 * 10 ** 18 / WEEK
# Weekly
MAX_ABS_RATE: constant(uint256) = 10_000_000 * 10 ** 18
RATE_REDUCTION_TIME: constant(uint256) = WEEK * 2
INFLATION_DELAY: constant(uint256) = 86400

mining_epoch: public(int128)
start_epoch_time: public(uint256)
rate: public(uint256)
committed_rate: public(uint256)
is_start: public(bool)

token: public(address)
controller: public(address)

# user -> gauge -> value
minted: public(HashMap[address, HashMap[address, uint256]])

# minter -> user -> can mint?
allowed_to_mint_for: public(HashMap[address, HashMap[address, bool]])

future_emergency_return: public(address)
emergency_return: public(address)
admin: public(address)  # Can and will be a smart contract
future_admin: public(address)  # Can and will be a smart contract

@external
def __init__(_token: address, _controller: address, _emergency_return: address, _admin: address):
    self.token = _token
    self.controller = _controller
    self.emergency_return = _emergency_return
    self.admin = _admin

    self.start_epoch_time = block.timestamp + INFLATION_DELAY - RATE_REDUCTION_TIME
    self.mining_epoch = -1
    self.is_start = True
    self.committed_rate = MAX_UINT256


@internal
def _update_mining_parameters():
    """
    @dev Update mining rate and supply at the start of the epoch
         Any modifying mining call must also call this
    """
    _rate: uint256 = self.rate

    self.start_epoch_time += RATE_REDUCTION_TIME
    self.mining_epoch += 1

    if _rate == 0 and self.is_start:
        _rate = INITIAL_RATE
        self.is_start = False
    else:
        _committed_rate: uint256 = self.committed_rate
        if _committed_rate != MAX_UINT256:
          _rate = _committed_rate
          self.committed_rate = MAX_UINT256

    self.rate = _rate

    log UpdateMiningParameters(block.timestamp, _rate)

@external
def update_mining_parameters():
    """
    @notice Update mining rate and supply at the start of the epoch
    @dev Callable by any address, but only once per epoch
         Total supply becomes slightly larger if this function is called late
    """
    assert block.timestamp >= self.start_epoch_time + RATE_REDUCTION_TIME  # dev: too soon!
    self._update_mining_parameters()

@external
def start_epoch_time_write() -> uint256:
    """
    @notice Get timestamp of the current mining epoch start
            while simultaneously updating mining parameters
    @return Timestamp of the epoch
    """
    _start_epoch_time: uint256 = self.start_epoch_time
    if block.timestamp >= _start_epoch_time + RATE_REDUCTION_TIME:
        self._update_mining_parameters()
        return self.start_epoch_time
    else:
        return _start_epoch_time

@external
def future_epoch_time_write() -> uint256:
    """
    @notice Get timestamp of the next mining epoch start
            while simultaneously updating mining parameters
    @return Timestamp of the next epoch
    """
    _start_epoch_time: uint256 = self.start_epoch_time
    if block.timestamp >= _start_epoch_time + RATE_REDUCTION_TIME:
        self._update_mining_parameters()
        return self.start_epoch_time + RATE_REDUCTION_TIME
    else:
        return _start_epoch_time + RATE_REDUCTION_TIME

@internal
def _mint_for(gauge_addr: address, _for: address):
    assert GaugeController(self.controller).gauge_types(gauge_addr) >= 0  # dev: gauge is not added

    LiquidityGauge(gauge_addr).user_checkpoint(_for)
    total_mint: uint256 = LiquidityGauge(gauge_addr).integrate_fraction(_for)
    to_mint: uint256 = total_mint - self.minted[_for][gauge_addr]

    if to_mint != 0:
        ERC20(self.token).transfer(_for, to_mint)
        if block.timestamp >= self.start_epoch_time + RATE_REDUCTION_TIME:
          self._update_mining_parameters()
        self.minted[_for][gauge_addr] = total_mint

        log Minted(_for, gauge_addr, total_mint)


@external
@nonreentrant('lock')
def mint(gauge_addr: address):
    """
    @notice Mint everything which belongs to `msg.sender` and send to them
    @param gauge_addr `LiquidityGauge` address to get mintable amount from
    """
    self._mint_for(gauge_addr, msg.sender)


@external
@nonreentrant('lock')
def mint_many(gauge_addrs: address[8]):
    """
    @notice Mint everything which belongs to `msg.sender` across multiple gauges
    @param gauge_addrs List of `LiquidityGauge` addresses
    """
    for i in range(8):
        if gauge_addrs[i] == ZERO_ADDRESS:
            break
        self._mint_for(gauge_addrs[i], msg.sender)


@external
@nonreentrant('lock')
def mint_for(gauge_addr: address, _for: address):
    """
    @notice Mint tokens for `_for`
    @dev Only possible when `msg.sender` has been approved via `toggle_approve_mint`
    @param gauge_addr `LiquidityGauge` address to get mintable amount from
    @param _for Address to mint to
    """
    if self.allowed_to_mint_for[msg.sender][_for]:
        self._mint_for(gauge_addr, _for)


@external
def toggle_approve_mint(minting_user: address):
    """
    @notice allow `minting_user` to mint for `msg.sender`
    @param minting_user Address to toggle permission for
    """
    self.allowed_to_mint_for[minting_user][msg.sender] = not self.allowed_to_mint_for[minting_user][msg.sender]

@external
def recover_balance(_coin: address) -> bool:
    """
    @notice Recover ERC20 tokens from this contract
    @dev Tokens are sent to the emergency return address.
    @param _coin Token address
    @return bool success
    """
    assert msg.sender == self.admin # dev: admin only

    amount: uint256 = ERC20(_coin).balanceOf(self)
    response: Bytes[32] = raw_call(
        _coin,
        concat(
            method_id("transfer(address,uint256)"),
            convert(self.emergency_return, bytes32),
            convert(amount, bytes32),
        ),
        max_outsize=32,
    )
    if len(response) != 0:
        assert convert(response, bool)

    return True

@external
def commit_next_emission(_rate_per_week: uint256):
  """
  @notice Commit a new rate for the following week (we update by weeks).
          _rate_per_week should have no decimals (ex: if we want to reward 600_000 RBN over the course of a week, we pass in 600_000 * 10 ** 18)
  """
  assert msg.sender == self.admin # dev: admin only
  assert _rate_per_week <= MAX_ABS_RATE # dev: preventing fatfinger
  new_rate: uint256 = _rate_per_week / WEEK
  self.committed_rate = new_rate
  log CommitNextEmission(new_rate)

@external
def commit_transfer_emergency_return(addr: address):
    """
    @notice Update emergency ret. of Minter to `addr`
    @param addr Address to have emergency ret. transferred to
    """
    assert msg.sender == self.admin  # dev: admin only
    self.future_emergency_return = addr
    log CommitEmergencyReturn(addr)

@external
def apply_transfer_emergency_return():
    """
    @notice Apply pending emergency ret. update
    """
    assert msg.sender == self.admin  # dev: admin only
    _emergency_return: address = self.future_emergency_return
    assert _emergency_return != ZERO_ADDRESS  # dev: emergency return not set
    self.emergency_return = _emergency_return
    log ApplyEmergencyReturn(_emergency_return)

@external
def commit_transfer_ownership(addr: address):
    """
    @notice Transfer ownership of GaugeController to `addr`
    @param addr Address to have ownership transferred to
    """
    assert msg.sender == self.admin  # dev: admin only
    self.future_admin = addr
    log CommitOwnership(addr)

@external
def apply_transfer_ownership():
    """
    @notice Apply pending ownership transfer
    """
    assert msg.sender == self.admin  # dev: admin only
    _admin: address = self.future_admin
    assert _admin != ZERO_ADDRESS  # dev: admin not set
    self.admin = _admin
    log ApplyOwnership(_admin)

Contract Security Audit

Contract ABI

[{"name":"Minted","inputs":[{"name":"recipient","type":"address","indexed":true},{"name":"gauge","type":"address","indexed":false},{"name":"minted","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"UpdateMiningParameters","inputs":[{"name":"time","type":"uint256","indexed":false},{"name":"rate","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"CommitNextEmission","inputs":[{"name":"rate","type":"uint256","indexed":false}],"anonymous":false,"type":"event"},{"name":"CommitEmergencyReturn","inputs":[{"name":"admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ApplyEmergencyReturn","inputs":[{"name":"admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"CommitOwnership","inputs":[{"name":"admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"name":"ApplyOwnership","inputs":[{"name":"admin","type":"address","indexed":false}],"anonymous":false,"type":"event"},{"stateMutability":"nonpayable","type":"constructor","inputs":[{"name":"_token","type":"address"},{"name":"_controller","type":"address"},{"name":"_emergency_return","type":"address"},{"name":"_admin","type":"address"}],"outputs":[]},{"stateMutability":"nonpayable","type":"function","name":"update_mining_parameters","inputs":[],"outputs":[],"gas":155943},{"stateMutability":"nonpayable","type":"function","name":"start_epoch_time_write","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":158152},{"stateMutability":"nonpayable","type":"function","name":"future_epoch_time_write","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":158341},{"stateMutability":"nonpayable","type":"function","name":"mint","inputs":[{"name":"gauge_addr","type":"address"}],"outputs":[],"gas":268280},{"stateMutability":"nonpayable","type":"function","name":"mint_many","inputs":[{"name":"gauge_addrs","type":"address[8]"}],"outputs":[],"gas":1745103},{"stateMutability":"nonpayable","type":"function","name":"mint_for","inputs":[{"name":"gauge_addr","type":"address"},{"name":"_for","type":"address"}],"outputs":[],"gas":270873},{"stateMutability":"nonpayable","type":"function","name":"toggle_approve_mint","inputs":[{"name":"minting_user","type":"address"}],"outputs":[],"gas":38141},{"stateMutability":"nonpayable","type":"function","name":"recover_balance","inputs":[{"name":"_coin","type":"address"}],"outputs":[{"name":"","type":"bool"}],"gas":14650},{"stateMutability":"nonpayable","type":"function","name":"commit_next_emission","inputs":[{"name":"_rate_per_week","type":"uint256"}],"outputs":[],"gas":39683},{"stateMutability":"nonpayable","type":"function","name":"commit_transfer_emergency_return","inputs":[{"name":"addr","type":"address"}],"outputs":[],"gas":39715},{"stateMutability":"nonpayable","type":"function","name":"apply_transfer_emergency_return","inputs":[],"outputs":[],"gas":41806},{"stateMutability":"nonpayable","type":"function","name":"commit_transfer_ownership","inputs":[{"name":"addr","type":"address"}],"outputs":[],"gas":39775},{"stateMutability":"nonpayable","type":"function","name":"apply_transfer_ownership","inputs":[],"outputs":[],"gas":41866},{"stateMutability":"view","type":"function","name":"mining_epoch","inputs":[],"outputs":[{"name":"","type":"int128"}],"gas":2850},{"stateMutability":"view","type":"function","name":"start_epoch_time","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2880},{"stateMutability":"view","type":"function","name":"rate","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2910},{"stateMutability":"view","type":"function","name":"committed_rate","inputs":[],"outputs":[{"name":"","type":"uint256"}],"gas":2940},{"stateMutability":"view","type":"function","name":"is_start","inputs":[],"outputs":[{"name":"","type":"bool"}],"gas":2970},{"stateMutability":"view","type":"function","name":"token","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3000},{"stateMutability":"view","type":"function","name":"controller","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3030},{"stateMutability":"view","type":"function","name":"minted","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"uint256"}],"gas":3592},{"stateMutability":"view","type":"function","name":"allowed_to_mint_for","inputs":[{"name":"arg0","type":"address"},{"name":"arg1","type":"address"}],"outputs":[{"name":"","type":"bool"}],"gas":3622},{"stateMutability":"view","type":"function","name":"future_emergency_return","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3120},{"stateMutability":"view","type":"function","name":"emergency_return","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3150},{"stateMutability":"view","type":"function","name":"admin","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3180},{"stateMutability":"view","type":"function","name":"future_admin","inputs":[],"outputs":[{"name":"","type":"address"}],"gas":3210}]

Deployed Bytecode

0x600436101561000d57610819565b60046000601c3760005134610af55763d43b40fa811861004e57600254621275008181830110610af557808201905090504210610af55761004c61081f565b005b63adc4cf4381186100b0576002546101405261014051621275008181830110610af5578082019050905042101561009557610140516101605260206101606100ae566100ae565b61009d61081f565b6002546101605260206101606100ae565bf35b63b26b238e811861013a576002546101405261014051621275008181830110610af5578082019050905042101561010b5761014051621275008181830110610af5578082019050905061016052602061016061013856610138565b61011361081f565b600254621275008181830110610af55780820190509050610160526020610160610138565bf35b636a627842811861017c576004358060a01c610af55761022052600054610af557600160005561022051610140523361016052610175610922565b6000600055005b63a51e19048118610274576004358060a01c610af557610220526024358060a01c610af557610240526044358060a01c610af557610260526064358060a01c610af557610280526084358060a01c610af5576102a05260a4358060a01c610af5576102c05260c4358060a01c610af5576102e05260e4358060a01c610af55761030052600054610af557600160005561032060006008818352015b610220610320516008811015610af55760200201516102355761026b565b610220610320516008811015610af557602002015161014052336101605261025b610922565b8151600101808352811415610217575b50506000600055005b6327f18ae381186102eb576004358060a01c610af557610220526024358060a01c610af55761024052600054610af557600160005560093360a05260805260406080206102405160a052608052604060802054156102e457610220516101405261024051610160526102e4610922565b6000600055005b63dd289d608118610341576004358060a01c610af55760e052600960e05160a05260805260406080203360a05260805260406080205415600960e05160a05260805260406080203360a052608052604060802055005b63db2f5f7981186104a1576004358060a01c610af55760e052600c543318610af5576370a082316101205230610140526020610120602461013c600060e0515af1610391573d600060003e3d6000fd5b601f3d1115610af557610120516101005260006004610160527fa9059cbb00000000000000000000000000000000000000000000000000000000610180526101606004806020846101a00101826020850160045afa505080518201915050600b546020826101a0010152602081019050610100516020826101a0010152602081019050806101a0526101a0505060206102406101a0516101c0600060e0515af1610440573d600060003e3d6000fd5b61022060203d8082116104535781610455565b805b905090508152805160200180610120828460045afa905050506000610120511461049457610140516101205181816020036008021c9050905015610af5575b6001610160526020610160f35b63733d39f4811861051057600c543318610af5576a084595161401484a00000060043511610af55760043562093a808082049050905060e05260e0516004557f42152d0007dbdd6390ad61a899e10fdf351c25d8ead1d2104cd506f7bb02600d60e051610100526020610100a1005b63ef0c7c828118610568576004358060a01c610af55760e052600c543318610af55760e051600a557f25c790a7d612ba9aa2630b1e99a1c79e94200e723561c945ae21661a4f1078b960e051610100526020610100a1005b6307fa40c281186105c257600c543318610af557600a5460e052600060e05114610af55760e051600b557f935a0ec5f76d1f31afb472d8d8411cb3b4551dcb02bbf02d821143d1fbfa368860e051610100526020610100a1005b636b441a40811861061a576004358060a01c610af55760e052600c543318610af55760e051600d557f2f56810a6bf40af059b96d3aea4db54081f378029a518390491093a7b67032e960e051610100526020610100a1005b636a1c05ae811861067457600c543318610af557600d5460e052600060e05114610af55760e051600c557febee2d5739011062cb4f14113f3b36bf0ffe3da5c0568f64189d1012a118910560e051610100526020610100a1005b63f9a40bf6811861068b5760015460e052602060e0f35b637375be2681186106a25760025460e052602060e0f35b632c4e722e81186106b95760035460e052602060e0f35b6323c1bad281186106d05760045460e052602060e0f35b63b208629c81186106e75760055460e052602060e0f35b63fc0c546a81186106fe5760065460e052602060e0f35b63f77c479181186107155760075460e052602060e0f35b638b752bb08118610768576004358060a01c610af55760e0526024358060a01c610af55761010052600860e05160a05260805260406080206101005160a052608052604060802054610120526020610120f35b63a099003381186107bb576004358060a01c610af55760e0526024358060a01c610af55761010052600960e05160a05260805260406080206101005160a052608052604060802054610120526020610120f35b63afc5ffc481186107d257600a5460e052602060e0f35b632c3f531e81186107e957600b5460e052602060e0f35b63f851a440811861080057600c5460e052602060e0f35b6317f7182a811861081757600d5460e052602060e0f35b505b60006000fd5b60035460e05260028054621275008181830110610af557808201905090508155506001805460018082018060801d81607f1d18610af5579050905081555060e0511561086c576000610870565b6005545b6108d557600454610100527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010051146108e7576101005160e0527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6004556108e7565b6705bc8c89959da74760e05260006005555b60e0516003557f8c1f077f7ef6438f97e353be8e229c7c49d3cad572d32be6de3033311a3ede3a426101005260e051610120526040610100a1565b6000633f9095b761018052610140516101a0526020610180602461019c6007545afa610953573d600060003e3d6000fd5b601f3d1115610af5576101805112610af557634b82009361018052610160516101a0526020610180602461019c6000610140515af1610997573d600060003e3d6000fd5b601f3d1115610af5576101805063094007076101a052610160516101c05260206101a060246101bc610140515afa6109d4573d600060003e3d6000fd5b601f3d1115610af5576101a051610180526101805160086101605160a05260805260406080206101405160a052608052604060802054808210610af557808203905090506101a05260006101a05114610af35763a9059cbb6101c052610160516101e0526101a0516102005260206101c060446101dc60006006545af1610a60573d600060003e3d6000fd5b601f3d1115610af5576101c050600254621275008181830110610af557808201905090504210610a9257610a9261081f565b6101805160086101605160a05260805260406080206101405160a052608052604060802055610160517f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f0610140516101c052610180516101e05260406101c0a25b565b600080fd

Block Transaction Difficulty 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
Loading...
Loading
[ 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.