Skip to content

Commit

Permalink
feat: add fuzzed amm to fuzzing scenario
Browse files Browse the repository at this point in the history
  • Loading branch information
cdummett committed May 24, 2024
1 parent 222990f commit bf3f3b1
Show file tree
Hide file tree
Showing 3 changed files with 298 additions and 0 deletions.
87 changes: 87 additions & 0 deletions vega_sim/scenario/fuzzed_markets/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -1613,3 +1613,90 @@ def finalise(self):
f" {self.accepted_proposals}/{self.proposals} valid governance transfer"
" proposals."
)


class FuzzedAutomatedMarketMaker(StateAgentWithWallet):

NAME_BASE = "FuzzedAutomatedMarketMaker"

def __init__(
self,
key_name: str,
market_name: str,
submit_probability: float = 0.50,
amend_probability: float = 0.10,
cancel_probability: float = 0.05,
initial_asset_mint: float = 1e9,
random_state: Optional[RandomState] = None,
tag: Optional[str] = None,
wallet_name: Optional[str] = None,
state_update_freq: Optional[int] = None,
):
super().__init__(key_name, tag, wallet_name, state_update_freq)

self.market_name = market_name
self.submit_probability = submit_probability
self.amend_probability = amend_probability
self.cancel_probability = cancel_probability
self.initial_asset_mint = initial_asset_mint

self.random_state = random_state if random_state is not None else RandomState()

def initialise(
self,
vega: VegaServiceNull,
create_key: bool = True,
mint_key: bool = False,
):
super().initialise(vega, create_key, mint_key)

self.market_id = self.vega.find_market_id(name=self.market_name)
self.asset_id = self.vega.market_to_asset[self.market_id]

asset_ids = [
self.vega.market_to_settlement_asset[self.market_id],
self.vega.market_to_base_asset[self.market_id],
self.vega.market_to_quote_asset[self.market_id],
]
for asset_id in asset_ids:
if asset_id is not None and mint_key:
# Top up asset
self.vega.mint(
wallet_name=self.wallet_name,
asset=asset_id,
amount=self.initial_asset_mint,
key_name=self.key_name,
)
self.vega.wait_for_total_catchup()

def step(self, vega_state) -> None:
if self.random_state.rand() < self.submit_probability:
transaction = fuzzers.fuzz_submit_amm(
vega=self.vega, rs=self.random_state, bias=0.8
)
self.vega.submit_transaction(
key_name=self.key_name,
transaction=transaction,
transaction_type="submit_amm",
wallet_name=self.wallet_name,
)
if self.random_state.rand() < self.amend_probability:
transaction = fuzzers.fuzz_amend_amm(
vega=self.vega, rs=self.random_state, bias=0.8
)
self.vega.submit_transaction(
key_name=self.key_name,
transaction=transaction,
transaction_type="amend_amm",
wallet_name=self.wallet_name,
)
if self.random_state.rand() < self.cancel_probability:
transaction = fuzzers.fuzz_cancel_amm(
vega=self.vega, rs=self.random_state, bias=0.8
)
self.vega.submit_transaction(
key_name=self.key_name,
transaction=transaction,
transaction_type="cancel_amm",
wallet_name=self.wallet_name,
)
189 changes: 189 additions & 0 deletions vega_sim/scenario/fuzzed_markets/fuzzers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import vega_sim.builders as build
import vega_sim.proto.vega as vega_protos

from typing import Union


def valid(rs, bias) -> bool:
if rs.rand() < bias:
Expand Down Expand Up @@ -766,3 +768,190 @@ def _pick_size_delta():
size_delta=size_delta,
price=price,
)


def fuzz_submit_amm(
vega: VegaService, rs: RandomState, bias: float
) -> vega_protos.commands.v1.commands.SubmitAMM:

def _pick_market_id():
if len(market_ids) == 0:
return None
return rs.choice(market_ids)

def _pick_commitment_amount():
return rs.rand() * 10000

def _pick_slippage_tolerance():
return rs.rand()

def _pick_proposed_fee():
return rs.rand()

def _pick_base():
if valid(rs, bias):
factor = rs.uniform(1, 2)
else:
factor = rs.uniform(0, 2)
return market_data.mid_price * factor

def _pick_lower_bound():
if valid(rs, bias):
factor = rs.uniform(0, 1)
else:
factor = rs.uniform(0, 2)
return rs.choice([None, base * factor])

def _pick_upper_bound():
if valid(rs, bias):
factor = rs.uniform(1, 2)
else:
factor = rs.uniform(0, 2)
return rs.choice([None, base * factor])

def _pick_leverage_at_lower_bound():
if valid(rs, bias):
if lower_bound is None:
return None
return rs.rand() * 100

def _pick_leverage_at_upper_bound():
if valid(rs, bias):
if upper_bound is None:
return None
return rs.rand() * 100

market_ids = [key for key, _ in vega.market_to_asset.items()]
market_id = _pick_market_id()
market_data = vega.market_data_from_feed(market_id)

proposed_fee = _pick_proposed_fee()
commitment_amount = _pick_commitment_amount()
slippage_tolerance = _pick_slippage_tolerance()

base = _pick_base()
lower_bound = _pick_lower_bound()
upper_bound = _pick_upper_bound()
leverage_at_lower_bound = _pick_leverage_at_lower_bound()
leverage_at_upper_bound = _pick_leverage_at_upper_bound()

return build.commands.commands.submit_amm(
asset_decimals=vega.asset_decimals,
market_asset_map=vega.market_to_asset,
market_price_decimals=vega.market_price_decimals,
market_id=market_id,
commitment_amount=commitment_amount,
slippage_tolerance=slippage_tolerance,
proposed_fee=proposed_fee,
base=base,
lower_bound=lower_bound,
upper_bound=upper_bound,
leverage_at_lower_bound=leverage_at_lower_bound,
leverage_at_upper_bound=leverage_at_upper_bound,
)


def fuzz_amend_amm(
vega: VegaService, rs: RandomState, bias: float
) -> vega_protos.commands.v1.commands.AmendAMM:

def _pick_market_id():
if len(market_ids) == 0:
return None
return rs.choice(market_ids)

def _pick_commitment_amount():
return rs.rand() * 10000

def _pick_slippage_tolerance():
return rs.rand()

def _pick_proposed_fee():
return rs.rand()

def _pick_base():
if valid(rs, bias):
factor = rs.uniform(1, 2)
else:
factor = rs.uniform(0, 2)
return market_data.mid_price * factor

def _pick_lower_bound():
if valid(rs, bias):
factor = rs.uniform(0, 1)
else:
factor = rs.uniform(0, 2)
return rs.choice([None, base * factor])

def _pick_upper_bound():
if valid(rs, bias):
factor = rs.uniform(1, 2)
else:
factor = rs.uniform(0, 2)
return rs.choice([None, base * factor])

def _pick_leverage_at_lower_bound():
if valid(rs, bias):
if lower_bound is None:
return None
return rs.rand() * 100

def _pick_leverage_at_upper_bound():
if valid(rs, bias):
if upper_bound is None:
return None
return rs.rand() * 100

market_ids = [key for key, _ in vega.market_to_asset.items()]
market_id = _pick_market_id()
market_data = vega.market_data_from_feed(market_id)

proposed_fee = _pick_proposed_fee()
commitment_amount = _pick_commitment_amount()
slippage_tolerance = _pick_slippage_tolerance()

base = _pick_base()
lower_bound = _pick_lower_bound()
upper_bound = _pick_upper_bound()
leverage_at_lower_bound = _pick_leverage_at_lower_bound()
leverage_at_upper_bound = _pick_leverage_at_upper_bound()

return build.commands.commands.amend_amm(
asset_decimals=vega.asset_decimals,
market_asset_map=vega.market_to_asset,
market_price_decimals=vega.market_price_decimals,
market_id=market_id,
commitment_amount=commitment_amount,
slippage_tolerance=slippage_tolerance,
proposed_fee=proposed_fee,
base=base,
lower_bound=lower_bound,
upper_bound=upper_bound,
leverage_at_lower_bound=leverage_at_lower_bound,
leverage_at_upper_bound=leverage_at_upper_bound,
)


def fuzz_cancel_amm(
vega: VegaService, rs: RandomState, bias: float
) -> vega_protos.commands.v1.commands.CancelAMM:

def _pick_market_id():
if len(market_ids) == 0:
return None
return rs.choice(market_ids)

def _pick_method():
values = vega_protos.vega.DispatchMetric.values()
if valid(rs, bias):
values.pop(0)
return rs.choice(values)

market_ids = [key for key, _ in vega.market_to_asset.items()]
market_id = _pick_market_id()
method = _pick_method()

return build.commands.commands.cancel_amm(
market_id=market_id,
method=method,
)
22 changes: 22 additions & 0 deletions vega_sim/scenario/fuzzing/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from vega_sim.scenario.fuzzed_markets.agents import (
FuzzingAgent,
FuzzyLiquidityProvider,
FuzzedAutomatedMarketMaker,
FuzzyReferralProgramManager,
FuzzyVolumeDiscountProgramManager,
)
Expand Down Expand Up @@ -138,6 +139,27 @@ def configure_agents(
for i_referrer, i_agent in itertools.product(range(2), range(2))
]
)
extra_agents.extend(
[
ReferralAgentWrapper(
agent=FuzzedAutomatedMarketMaker(
wallet_name="FuzzedAutomatedMarketMaker",
key_name=(
f"FuzzedAutomatedMarketMaker{str(i_referrer).zfill(3)}_{str(i_agent).zfill(3)}"
),
market_name=market_name,
submit_probability=0.5,
amend_probability=0.5,
cancel_probability=0.1,
initial_asset_mint=1e6,
tag=f"{market_code}_{str(i_referrer).zfill(3)}_{str(i_agent).zfill(3)}",
),
referrer_wallet_name="ReferralAgentWrapper",
referrer_key_name=f"ReferralAgentWrapper_{str(i_referrer).zfill(3)}",
)
for i_referrer, i_agent in itertools.product(range(2), range(2))
]
)

# Create a reward funder for each asset and each reward type
asset_names = set()
Expand Down

0 comments on commit bf3f3b1

Please sign in to comment.