ETH Price: $3,362.96 (-1.57%)
Gas: 9 Gwei

Contract

0x5B0655F938A72052c46d2e94D206ccB6FF625A3A
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Mint201751152024-06-26 9:58:119 hrs ago1719395891IN
Ribbon Finance: Minter
0 ETH0.000976133.49613555
Mint201612222024-06-24 11:23:592 days ago1719228239IN
Ribbon Finance: Minter
0 ETH0.001172463.48560334
Mint201537112024-06-23 10:12:113 days ago1719137531IN
Ribbon Finance: Minter
0 ETH0.000559422.18085239
Mint201508842024-06-23 0:41:353 days ago1719103295IN
Ribbon Finance: Minter
0 ETH0.000449861.75375167
Mint201377802024-06-21 4:43:115 days ago1718944991IN
Ribbon Finance: Minter
0 ETH0.001130323.50977671
Mint201069092024-06-16 21:02:119 days ago1718571731IN
Ribbon Finance: Minter
0 ETH0.001243133.78110982
Mint201029112024-06-16 7:38:5910 days ago1718523539IN
Ribbon Finance: Minter
0 ETH0.001116952.79210377
Mint201029052024-06-16 7:37:4710 days ago1718523467IN
Ribbon Finance: Minter
0 ETH0.000896092.94170225
Mint200902022024-06-14 12:59:4712 days ago1718369987IN
Ribbon Finance: Minter
0 ETH0.003093388.11121663
Mint200571622024-06-09 22:10:3516 days ago1717971035IN
Ribbon Finance: Minter
0 ETH0.002072526.85872553
Mint200504212024-06-08 23:33:3517 days ago1717889615IN
Ribbon Finance: Minter
0 ETH0.001037264
Mint200478432024-06-08 14:55:4718 days ago1717858547IN
Ribbon Finance: Minter
0 ETH0.001948527.34287647
Mint200385712024-06-07 7:51:1119 days ago1717746671IN
Ribbon Finance: Minter
0 ETH0.003149589.77976593
Mint199712732024-05-28 22:13:3528 days ago1716934415IN
Ribbon Finance: Minter
0 ETH0.001845629.43981575
Mint199712702024-05-28 22:12:5928 days ago1716934379IN
Ribbon Finance: Minter
0 ETH0.002989549.05002798
Mint199169882024-05-21 8:07:4736 days ago1716278867IN
Ribbon Finance: Minter
0 ETH0.003919248.65312465
Mint198923962024-05-17 21:33:5939 days ago1715981639IN
Ribbon Finance: Minter
0 ETH0.000971433.34606314
Mint198791122024-05-16 0:58:5941 days ago1715821139IN
Ribbon Finance: Minter
0 ETH0.001336213.64679387
Mint198786432024-05-15 23:23:4741 days ago1715815427IN
Ribbon Finance: Minter
0 ETH0.000919413.29296806
Mint198776232024-05-15 19:58:3541 days ago1715803115IN
Ribbon Finance: Minter
0 ETH0.002964110.71842702
Mint198775172024-05-15 19:37:2341 days ago1715801843IN
Ribbon Finance: Minter
0 ETH0.002219968.94201161
Mint198775042024-05-15 19:34:4741 days ago1715801687IN
Ribbon Finance: Minter
0 ETH0.002216788.54410864
Mint198742892024-05-15 8:49:2342 days ago1715762963IN
Ribbon Finance: Minter
0 ETH0.001415285.70096669
Mint198689852024-05-14 14:59:4743 days ago1715698787IN
Ribbon Finance: Minter
0 ETH0.0026074810.04995761
Mint198550812024-05-12 16:18:4745 days ago1715530727IN
Ribbon Finance: Minter
0 ETH0.001309644.69062253
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:
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.